mercredi 4 février 2015

Test completes without an exception, even though an exception should occur

I am currently working as an intern at a company and my task is to make a Continuous Integration environment so that they can compile, test and deploy their builds easier and faster.


Before I start making a lot of unit tests I was tasked with first trying to use a simple Operation and make a Unit Test based on that. It requires a ton of Mocking but in the end I made the test run successfully. The code is below:



@Test
public void testValidateInputSuccess()
{
Mockery context = new Mockery()
{
{
setImposteriser(ClassImposteriser.INSTANCE);
}
};

String InvoiceID = "55555-55555-55555-55555-55555";

omittedRequest r;
omittedResponse res;
ArtifactManager arti;
EntityManager em;
Invoice invoice;
r = context.mock(omittedRequest.class);
res = context.mock(omittedResponse.class);
arti = context.mock(ArtifactManager.class);
em = context.mock(EntityManager.class);
invoice = context.mock(Invoice.class);

context.checking(new Expectations()
{
{
allowing(r).hasRole("Fakturering");
will(returnValue(true));
allowing(r).getParamValue("invoiceid");
will(returnValue(InvoiceID));
allowing(r).getParamValue("eventRemark");
will(returnValue(null));
allowing(r).getArtifactManager();
will(returnValue(arti));

allowing(arti).getEntityManager();
will(returnValue(em));
allowing(em).find(Invoice.class, new DbGuid(InvoiceID));
will(returnValue(invoice));

allowing(res).getLanguageResource();
will(returnValue(null));
allowing(res).getDocument();
will(returnValue(null));

allowing(invoice).isDeleted();
will(returnValue(false));
allowing(invoice).getInvoiceNumber();
will(returnValue(null));

}
});

rejectinvoice re = new rejectinvoice();

try
{
re.service(r, res);
}
catch (Exception e)
{

assertTrue(re.inputIsValid());

}


}


This test will reach this part:



catch (Exception e)
{

assertTrue(re.inputIsValid());

}


As I use a lot of null values and Mocked objects. That's fine really, because the next step would be to create some XML from the rejectinvoice object and then show that to the end-user (I am not part of that).


But I wanted to be able to run this test without having to hit an exception so I looked at the mocking tools in JMock (That I am currently using) and I found that you can use the ignoring keyword to make a certain part of the code ignored (is my guess at least). But when I run the same test as above, but with this introduced instead of the exception handling:



rejectinvoice re = context.mock(rejectinvoice.class);
try
{
context.checking(new Expectations()
{
{
allowing(re).service(r, res);
ignoring((JsonWizOperation) re).executeOperation();
}
});
re.service(r, res);
} catch(ExecutionDeniedException e) {
e.printStackTrace();
} catch(Exception ex) {
ex.printStackTrace();
}


I reach the end of the code without any exceptions whatsoever, even if I am supposed to reach an exception. The executeOperations() method is defined as such:



protected abstract void executeOperation() throws Exception;


In an Abstract class called JsonWizOperation. I choose to "stop" at executeOperation because of this code that is run by rejectinvoice



public void service(omittedRequest request, omittedResponse response) throws Exception
{
this.omittedRequest = request;
this.omittedResponse = response;
try
{
validateInputs();
if (inputIsValid())
executeOperation();
}
finally
{
createReply();
}
}


I don't want it to reach createReply() because regardless of what I do, it will always return a NullPointerException, because it works with Mock objects that got null values left, right and center.


So why is it I don't get any exceptions back, when in fact the signatures of the methods I use, indicates that an exception should be thrown?


Aucun commentaire:

Enregistrer un commentaire