I am trying to mock a FileWriter so that my test will not create the file. The code is running ordinary but I can not create a proper test.
JSONExporter
public void exportFile(List<Employee> employeeList) throws ExportFileException {
try (Writer writer = new FileWriter("filepath")) {
Gson gson = new GsonBuilder()
.setPrettyPrinting() //prints the json file with json indenting
.create();
gson.toJson(employeeList, writer);
} catch (IOException ex) {
throw new ExportFileException();
}
}
TestJSONExporter
#Injectable FileWriter mockedFileWriter;
#Test
void testExportFile_whenFilenameIsValid_willDoNothing(#Mocked Gson mockedGson) throws IOException {
new Expectations() {{
new FileWriter(anyString); result = mockedFileWriter;
mockedGson.toJson(any, (FileWriter) any);
}};
Assertions.assertDoesNotThrow( () -> jsonFileExporter.exportFile("filename", Role.SELLER, employeeList));
}
Console
java.io.FileNotFoundException: (Result too large)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at java.io.FileWriter.<init>(FileWriter.java:63)
at com.eurodyn.training.export.JSONFileExporterTest$1.<init>(JSONFileExporterTest.java:59)
at com.eurodyn.training.export.JSONFileExporterTest.testExportFile_whenFilenameIsValid_willDoNothing(JSONFileExporterTest.java:58)
Does anyone know if there is a way to do it with either jmockit or mockito. PowerMock is not compatible with JUnit 5 i think.
Related
I am trying yo unit test my method which internally calls DB which I am trying to mock and want to return the response but getting an error.
public void processAlert(JsonObject requestInput, Handler<AsyncResult<JsonObject>> handler) {
JsonObject jobInput = new JsonObject().put("requestInput", requestInput);
dbService.saveJobDetails(jobInput, readyHandler -> {
if (readyHandler.succeeded()) {
handler.handle(Future.succeededFuture(readyHandler.result()));
} else {
handler.handle(Future.failedFuture(readyHandler.cause()));
}
});
}
Test code for mocking the dbService
#Mock
DBService dbService;
#Captor
private ArgumentCaptor<Handler<AsyncResult<JsonObject>>> resultHandlerCaptor;
#Test
public void test() {
AsyncResult<JsonObject> result = Future.succeededFuture(new JsonObject().put("status", "success"));
Mockito.verify(dbService).saveJobDetails(Mockito.any(JsonObject.class), resultHandlerCaptor.capture());
Handler<AsyncResult<JsonObject>> handler = resultHandlerCaptor.getValue();
handler.handle(result);
But when I am running this test getting an Exception
Wanted but not invoked:
dbService.saveJobDetails(
<any io.vertx.core.json.JsonObject>,
<Capturing argument>
);
Actually, there were zero interactions with this mock.
I am new to web services and spring boot. I have written a service for which I am now writing a test case.
My application gets Soap request, parses the body and saves contents into database.
My test case tests this service.
When I run the application and send a request from Postman, it runs alright. But when I call my service method from test case, I get nullpointer for JaxBcontext.
I have declared Jaxbcontext in my AppConfig.java (which is annotated with #Configuration and my jaxb is a bean with #Bean annotation) in my service, I have #autowire to use jaxbcontext.
I have pasted code snippets for clarity. Please advise me what I am doing wrongly here.
My test case
public class ReferralExchangeEndpointTest {
ReferralExchangeEndpoint referralExchangeEndpoint = new ReferralExchangeEndpoint();
JAXBContext jbcTest;
Marshaller marshaller;
Unmarshaller unmarshaller;
public ReferralExchangeEndpointTest() throws JAXBException {
}
#Before
public void setUp() throws Exception {
jbcTest = JAXBContext.newInstance(
"our app schema"); // this is working fine, I have replaced schema with this text for posting it in stack.
ObjectFactory factory = new ObjectFactory();
marshaller = jbcTest.createMarshaller();
unmarshaller = jbcTest.createUnmarshaller();
}
#Test
public void send() throws Exception {
File payload = new File("payload.xml");
Object x = unmarshaller.unmarshal(payload);
JAXBElement jbe = (JAXBElement) x;
System.out.println(jbe.getName());
Object test = jbe.getValue();
SendRequestMessage sendRequestMessage = (SendRequestMessage) jbe.getValue();
// Method in test.
referralExchangeEndpoint.send(sendRequestMessage);
}
}
My service class
#Endpoint
public class ReferralExchangeEndpoint {
public static final Logger logger = LoggerFactory.getLogger(ReferralExchangeEndpoint.class);
#Autowired
private JAXBContext jaxbContext;
#Autowired
.
.
.
private Form parseBody(String payLoadBody) {
try {
Unmarshaller um = jaxbContext.createUnmarshaller();
return (Form) um.unmarshal(new StringReader(payLoadBody));
} catch (Exception e) {
throw new RuntimeException("Failed to extract the form from the payload body", e);
}
}
My appconfig file
#Configuration
public class AppConfig {
#Bean
public JAXBContext jaxbContext() throws JAXBException {
return
JAXBContext.newInstance("packagename");
}
#Bean public MessagingService messagingService() {
return new MessagingService();
}
}
Thanks.
Kavitha.
** Solved **
My test case now looks like this.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {AppConfig.class})`
public class ReferralExchangeEndpointTest {
#Autowired
ReferralExchangeEndpoint referralExchangeEndpoint;
#Autowired
private JAXBContext jaxbContext;
private Marshaller marshaller;
private Unmarshaller unmarshaller;
#Before
public void setUp() throws Exception {
marshaller = jaxbContext.createMarshaller();
unmarshaller = jaxbContext.createUnmarshaller();
}
#Test
public void send() throws Exception {
File payload = new File("src/test/resources/payload.xml");
JAXBElement jbe = (JAXBElement) unmarshaller.unmarshal(payload);
SendRequestMessage sendRequestMessage = (SendRequestMessage) jbe.getValue();
JAXBElement<SendResponseMessage> response = referralExchangeEndpoint.send(sendRequestMessage);
//TODO add remaining assertions on response after confirming what should the service return for these attributes.
assertEquals("SiteId wrong in response: ", "siteId", response.getValue().getSiteId());
}
}`
Currently, whenever I need to fail a test in response to an exception thrown in another thread, I write something like this:
package com.example;
import java.util.ArrayList;
import java.util.List;
import org.testng.annotations.Test;
import static java.util.Arrays.asList;
import static java.util.Collections.synchronizedList;
import static org.testng.Assert.fail;
public final class T {
#Test
public void testFailureFromLambda() throws Throwable {
final List<Throwable> errors = synchronizedList(new ArrayList<>());
asList("0", "1", "2").parallelStream().forEach(s -> {
try {
/*
* The actual code under test here.
*/
throw new Exception("Error " + s);
} catch (final Throwable t) {
errors.add(t);
}
});
if (!errors.isEmpty()) {
errors.forEach(Throwable::printStackTrace);
final Throwable firstError = errors.iterator().next();
fail(firstError.getMessage(), firstError);
}
}
}
A synchronized list may be replaced with an AtomicReference<Throwable>, but in general the code remains pretty much the same.
Is there any standard (and less verbose) way of doing the same using any of test frameworks available in Java (TestNG, JUnit, Hamcrest, AssertJ, etc.)?
By default TestNG fails a test method when an exception is thrown from it. I believe the same thing happens with JUnit as well, wherein it marks a test as errored, if it throws an unexpected exception.
If you are to be dealing with Streams, then you would need to wrap it up within a RuntimeException variant, so that Java doesn't complain. TestNG would automatically fail the test.
Here's a sample :
#Test
public void testFailureFromLambdaRefactored() {
asList("0", "1", "2").parallelStream().forEach(s -> {
try {
/*
* The actual code under test here.
*/
if (s.equals("2")) {
throw new Exception("Error " + s);
}
} catch (final Throwable t) {
throw new RuntimeException(t);
}
});
}
This was for scenarios that involve lambdas and streams. In general if you would like to know about an exception that happens in a new thread spun off from a #Test method, then you would need to use ExecutorService.
Here's a sample :
#Test
public void testFailureInAnotherThread() throws InterruptedException, ExecutionException {
List<String> list = asList("0", "1", "2");
ExecutorService service = Executors.newFixedThreadPool(2);
List<Future<Void>> futures = service.invokeAll(Arrays.asList(new Worker(list)));
for (Future future : futures) {
future.get();
}
}
public static class Worker implements Callable<Void> {
private List<String> list;
public Worker(List<String> list) {
this.list = list;
}
#Override
public Void call() throws Exception {
for (String s : list) {
if (s.equals("2")) {
throw new Exception("Error " + s);
}
}
return null;
}
}
I am doing something similar to mentioned in
Example of using StreamingOutput as Response entity in Jersey
#GET
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response streamExample(#Context UriInfo uriInfo) {
StreamingOutput stream = new StreamingOutput() {
#Override
public void write(OutputStream os) throws IOException,WebApplicationException {
try{
Writer writer = new BufferedWriter(new OutputStreamWriter(os));
//Read resource from jar
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("public/" + uriInfo.getPath());
...//manipulate the inputstream and build string with StringBuilder here//.......
String inputData = builder.toString();
Writer writer = new BufferedWriter(new OutputStreamWriter(os));
writer.write(inputData);
writer.flush();
} catch (ExceptionE1) {
throw new WebApplicationException();
}
}
};
return Response.ok(stream,MediaType.APPLICATION_OCTET_STREAM).build();
}
I am trying to unit test this by mocking URIInfo like mentioned in How to get instance of javax.ws.rs.core.UriInfo
public void testStreamExample() throws IOException, URISyntaxException {
UriInfo mockUriInfo = mock(UriInfo.class);
Mockito.when(mockUriInfo.getPath()).thenReturn("unusal-path");
Response response = myresource.streamExample(mockUriInfo);}
I want to be able to check that I get an Exception when I switch the path to jar to something else.But, when I run/debug the test, I never enter the
public void write(OutputStream os) throws IOException,
WebApplicationException {...}
part and I only always hit the return Response.ok(stream,MediaType.APPLICATION_OCTET_STREAM).build();
Am I missing something very obvious here??
Because the stream is not written to until it hits the MessageBodyWriter (which is the component that ends up calling the StreamingOutput#write).
What you can do, is just get the Response from the return and call Response#getEntity() (which returns an Object) and cast it to StreamingOutput. Then call the write method yourself, passing an OutputStream, maybe a ByteArrayOutputStream so you can get the contents as a byte[] to check it. It all would look something like
UriInfo mockInfo = mockUriInfo();
Response response = resource.streamExample(mockInfo);
StreamingOutput output = (StreamingOutput) response.getEntity();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
output.write(baos);
byte[] data = baos.toByteArray();
String s = new String(data, StandardCharsets.UTF_8);
assertThat(s, is("SomeCharacterData"));
Just started using Scala for unit testing and am totally confused as to how exceptions are handled in Scala. Below is an example of a JUnit test.
class Test {
#Test
void someTest {
try {
//Something
} catch(Exception e) {
Assert.assertTrue(e.getCause() instanceOf IOException);
}
}
}
Now I want to do the same thing in Scala, I tried
class Test {
#Test def someTest {
try {
//Something
} catch {
case e: Exception => assertTrue(e.getCause().isInstanceOf[IOException])
}
}
}
But my IDE keeps complaining that Method Apply is not a member of type Any. I read about exception handling in Scala and found that you should use a pattern matcher and that there is no exception handling in Scala. How exactly does this work?
If you are testing scala code I suggest using something more scalish than jUnit like ScalaTest.
import java.io.IOException
import org.scalatest._
import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers
object SomeCode
{
def apply() = {
throw new IOException
}
}
class SomeTest
extends FlatSpec
with ShouldMatchers
{
"Something" should "throw an IOException, TODO: why ?" in
{
intercept[IOException] {
SomeCode()
}
}
it should "also throw an IOException here" in
{
evaluating { SomeCode() } should produce [IOException]
}
}
nocolor.run( new SomeTest )