I'm working into a method trying to change the default rest-assured log (which goes to the console) to a file using log4j.
It's a JUnit project which methods finally call to a REST facade, which have methods like this one.
private ResponseSpecification responseSpecification(RequestSpecification requestSpecification, Matcher matcher, int statusCode) {
ResponseSpecification responseSpecification = requestSpecification.expect().statusCode(StatusCode).body(".", is(matcher));
if (log) {
responseSpecification = responseSpecification.log().all();
}
return responseSpecification;
}
Following the official doc, I've changed the method like this:
private ResponseSpecification responseSpecification(RequestSpecification requestSpecification, Matcher matcher, int statusCode) {
final StringWriter writer = new StringWriter();
final PrintStream captor = new PrintStream(new WriterOutputStream(writer), true);
ResponseSpecification responseSpecification = requestSpecification.filter(logResponseTo(captor)).expect().statusCode(statusCode).body(".", is(matcher));
System.out.println("writer = " + writer.toString() + " <-");
return responseSpecification;
}
But writer.toString()
prints always a void string (the old implementation works fine). Maybe I'm doing something wrong, but what? :(
I need to get something printable which can be managed by log4j, in this or other way.
Can anyone help me?
To log all request specification details including parameters, headers and body of the request, log(). all() needs to be added post given() section. This will print the response body regardless if an error occurred.
A filter allows you to inspect and alter a request before it's actually committed and also inspect and alter the response before it's returned to the expectations. You can regard it as an "around advice" in AOP terms. Filters can be used to implement custom authentication schemes, session management, logging etc.
I've just solved the problem writing this into the RestSuite.setUp()
method
RestAssured.config = config().logConfig(new LogConfig(defaultPrintStream));
and keeping intact the old code.
private ResponseSpecification responseSpecification(RequestSpecification requestSpecification, Matcher matcher, int statusCode) {
ResponseSpecification responseSpecification = requestSpecification.expect().statusCode(StatusCode).body(".", is(matcher));
if (log) {
responseSpecification = responseSpecification.log().all();
}
return responseSpecification;
}
I hope it can help to someone in a future.
Might be useful too: Here a class which redirects the restAssured log() calls to a supplied logger:
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import org.slf4j.Logger;
/**
* A wrapper class which takes a logger as constructor argument and offers a PrintStream whose flush
* method writes the written content to the supplied logger (debug level).
* <p>
* Usage:<br>
* initializing in @BeforeClass of the unit test:
* <pre>
* ToLoggerPrintStream loggerPrintStream = new ToLoggerPrintStream( myLog );
* RestAssured.config = RestAssured.config().logConfig(
* new LogConfig( loggerPrintStream.getPrintStream(), true ) );
* </pre>
* will redirect all log outputs of a ValidatableResponse to the supplied logger:
* <pre>
* resp.then().log().all( true );
* </pre>
*
* @version 1.0 (28.10.2015)
* @author Heri Bender
*/
public class ToLoggerPrintStream
{
/** Logger for this class */
private Logger myLog;
private PrintStream myPrintStream;
/**
* @return printStream
*/
public PrintStream getPrintStream()
{
if ( myPrintStream == null )
{
OutputStream output = new OutputStream()
{
private StringBuilder myStringBuilder = new StringBuilder();
@Override
public void write(int b) throws IOException
{
this.myStringBuilder.append((char) b );
}
/**
* @see java.io.OutputStream#flush()
*/
@Override
public void flush()
{
myLog.debug( this.myStringBuilder.toString() );
myStringBuilder = new StringBuilder();
}
};
myPrintStream = new PrintStream( output, true ); // true: autoflush must be set!
}
return myPrintStream;
}
/**
* Constructor
*
* @param aLogger
*/
public ToLoggerPrintStream( Logger aLogger )
{
super();
myLog = aLogger;
}
PrintStream fileOutPutStream = new PrintStream(new File("somefile.txt"));
RestAssured.config = config().logConfig(new LogConfig().defaultStream(fileOutPutStream));
Use a printStream to point to a file & give a filename you want to print the log. Put the above code in your setup method for the tests & then just call log on your RequestSpecification instance as below
requestSpecification.log().all();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With