I have a method which has the following code in it, it saves a order object to the orderStatus jpa repository and i have a try catch method which should capture the JDBC Connection exception.
How do i test this scenario using Junit and mockito?
try {
orderStatusRepository.save(newOrderStatus);
} catch (JDBCConnectionException ex) {
);
If the code is the goal is to test that in case JDBCConnectionException is thrown it is caught and not propagated I would suggest to mock orderStatusRepository using Mockito:
when(orderStatusRepository.save(newOrderStatus))
.thenThrow(JDBCConnectionException.class);
then execute the test and check that the method returns normally and that mocked object method was accessed (the exception therefor was thrown):
verify(orderStatusRepository).save(newOrderStatus);
Note that if save method doesn't return anything you would need to mock it a bit differently:
doThrow(JDBCConnectionException.class)
.when(orderStatusRepository).save(newOrderStatus);
follow the below code to test your code for the JDBC connection exception.
#MockBean
private OrderStatusRepository orderStatusRepository;
#Test
public void jdbcConnectionExceptionTest() {
try{
when(orderStatusRepository.save(newOrderStatus))
.thenThrow(JDBCConnectionException.class);
orderStatusRepository.save(newOrderStatus);
} catch (Exception e) {
assertTrue(e instanceof JDBCConnectionException);
}
}
Related
I am trying to write test for my controller with the code below. I want to cover the test for the code in the catch block statement but I'm not able to write one. I want to return a Server Response with failure code and message in the catch block.
#PostMapping(COUNTERS)
public ResponseEntity<?> getCounters(#Valid #RequestBody ApartmentCounterListRequest requestData) {
try {
log.debug("Entering API for counter list");
ApartmentCounterListResponse apartmentCounterListResponse = counterService.getAllCounters();
return ResponseEntity.ok(apartmentCounterListResponse);
} catch (Exception exception) {
log.error("Exception in counter list :: ", exception);
ServerResponse serverResponse = ResponseBuilder.buildVendorFailureMessage(new ServerResponse(),
RequestResponseCode.EXCEPTION);
return ResponseEntity.ok(JsonResponseBuilder.enquiryResponse(serverResponse));
}
}
My test code is as follows:
#Test
#DisplayName("Should return ServerResponse with failure data.")
void Should_Return_Server_Response_On_Exception() throws Exception {
/*given*/
ApartmentCounterListRequest apartmentCounterListRequest = ApartmentTestUtil.getApartmentCounterListRequest.
apply("test", "test");
Mockito.when(counterServic.getAllCounters()).thenThrow(new Exception());
// ServerResponse serverResponse = ApartmentTestUtil.getServerExceptionServerResponse.get();
/*then*/
mockMvc.perform(
post(COUNTER_URL)
.contentType(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(apartmentCounterListRequest)))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.resultCode", Matchers.is("-6")));
verify(counterService, times(1)).getAllCounters();
}
When I run this test I am getting the following error:
org.mockito.exceptions.base.MockitoException:
Checked exception is invalid for this method!
Invalid: java.lang.Exception
I have gone through some of the following posts but haven't found a suitable answer yet.
Unit testing code in catch block of a Spring Controller
Java - How to Test Catch Block?
Unit testing code in catch block of a Spring Controller
JUnit for both try and catch block coverage
Can anyone help me write test that covers the catch block or tell me the way to do it?
I have this try catch in my controller to handle any unexpected exceptions. And for different api's I have to send a response with different response code and messages which doesnot allow me to use Exception handler.
The method you are mocking does not declare a checked exception, therefore Mockito is not able to throw one from there. Try to have the mock throw an unchecked exception (i.e. RuntimeException).
You can try to use willAnswer
Mockito.when(counterServic.getAllCounters()).thenAnswer(x -> {throw new Exception() });
Maybe this is a bit misused as Answer is used for more complex for when return
I have a project with Morphia ORM - Without transactions. And I have this method:
public void methodForTest() {
try {
methodCanThrowException();
} catch (Exception e) {
methodWhiсhICanNotTest(template);
throw new Exception("message of exception");
}
}
private void methodWhiсhICanNotTest(String template){
serviceWhichCanBeMockOne.clearAll(template);
serviceWhichCanBeMockTwo.clearAll(template);
serviceWhichCanBeMockThree.clearAll(template);
}
Can I check that methodWhiсhICanNotTest(); was called? or how can I rewrite this code for easier testing?
UPDATE ANSWER FOR THE UPDATED QUESTION :D
If your methodWhiсhICanNotTest is a private method. Then you cannot verify it using Mockito in my previous answer. PowerMock is another solution for you. Read this article and try it :-)
=======================
You can use Mockito to verify whether methodWhiсhICanNotTest is called.
Mockito.verify(abc.methodWhiсhICanNotTest())
Below is the piece of code. Now already the exception is caught. How can I write the negative test for the same? To make sure code enters in catch block?
public ThirdPartyResponse load(ThirdPartyRequestContext context) {
ThirdPartyResponse thirdPartyResponse = new ThirdPartyResponse();
try
{
thirdPartyResponse.setData(getData(context));
}catch (Exception e)
{
LOGGER.error("Error executing {}", context.getEndpoint(), e);
thirdPartyResponse.setData(Collections.emptyList());
thirdPartyResponse.setErrorMessage(e.getMessage());
}
return thirdPartyResponse;
}
You can assert that error message is not null for the thirdPartyResponse object that's returned from your method:
assertNotNull(thirdPartyResponse.getErrorMessage());
import statement:
import static org.junit.Assert.assertNotNull;
// mock context so that getData(context) throws exception with message "foo"
...
ThirdPartyResponse response = load(context);
assertThat(response.getMessage(), is("foo"));
1st of all , don't try to catch main "Exception" in catch as it will catch all kind of exception which you may not even want to catch. Next, if you want to write test case for that you need to use Mockito for performing that negative test, you need to write something like this
Mockito.when(some_method(anyparam())).thenThrow(new YourCustomException("error message"));
probably you may need to mock inside getData() method.
As you are using mockito try following:
1) Alter the load method so that the thirdPartyResponse is a protected method call:
public ThirdPartyResponse load(ThirdPartyRequestContext context) {
ThirdPartyResponse thirdPartyResponse = createThirdPartyResponse();
2) Put creation of that object inside the createThirdPartyResponse():
protected ThirdPartyResponse createThirdPartyResponse(){
return new ThirdPartyResponse();
}
3) Spy on the SUT and mock the createThirdPartyResponse method:
public class ClassUnderTest{
#Spy
ClassUnderTest classUnderTestSpy;
#Spy
ThirdPartyResponse thirdPartyResponseSpy;
#BeforeClass
public void init(){
MockitoAnnotations.initMocks(this);
}
public void expectExceptionOnLoad(){
// Arrange
Mockito.doThrow(new Exception()).when(thirdPartyResponseMock.setData(Mockito.any(Object.class));
Mockito.doReturn(thirdPartyResponseSpy).when(classUnderTestSpy).createThirdPartyResponse();
// Act
classUnderTestSpy.load(context);
// Assert
assertNotNull(thirdPartyResponseSpy.getErrorMessage());
}
}
PS. you need to replace the Mockito.any(Object.class) with a adequate class
I have the following code:
try {
em.persist(myObject);
em.flush();
}
catch (Exception e) {
System.out.println("An Exception occur when trying to persist and flush");
}
In test I have mock my EntityManager with Mockito:
#Mock
EntityManager mockEm;
but as persist and flush are void methods, I'm not able able to write something like:
when(mockEm.persist(anObject).then(doSomeThing);
How can I write unit testing (with JUnit)to mock em.persist and em.flush in order to test both cases with and without exception?
Thanks.
I guess we need more details. For now, you can do something like this: (it's kind of pseudo-code).
#Test // it passess when there's one object in repository (I assume u have clean memory db)
public void shouldPersistMyObject() throws Exception {
em.persist(myObject);
em.flush();
Assert.assertThat(dao.findAll(), Matchers.equalTo(1));
}
#Test(expected = <YourDesiredException>.class) // if <YourDesiredException> is thrown, your test passes
public void shouldThrowExceptionWhenSavingCorruptedData() {
//set NULL on some #NotNull value, then save, like:
myObject.setUserId(null);
em.save(myObject); //exception is thrown
}
I'm trying to write some JUnit tests for an Android application.
I've read online that to have a unit test pass if it throws an exception, you would use the #Test annotation like this
#Test(expected = NullPointerException.class)
public void testNullValue() throws Throwable
{
Object o = null;
o.toString();
}
but Eclipse is telling me that this annotation doesn't exist. How can I fix this? If I run the test, it runs fine and fails as expected but obviously I want it to fail (and thus actually pass) :)
You can always bypass it manually:
public void testNullValue()
{
try {
Object o = null;
o.toString();
fail("Expected NullPointerException to be thrown");
} catch (NullPointerException e) {
assertTrue(true);
}
}
I believe that should be:
#Test(expected=NullPointerException.class)
Double check the JUnit version you are using
Do not use the JUnit that eclipse provides (Indigo) but import manually a JUnit 4.9 manually
The error is that "mysterious" error that has not an easy or immediate answer, I am only trying ideas