I would like to test that my custom exception is thrown when I call a method like that:
private MyObject queryDatabase(String request, String end){
HttpEntity myEntity = new NStringEntity(request, ContentType.APPLICATION_JSON)
Response response = restClient.performRequest("GET", end,Collections.emptyMap(), myEntity)
MyObject myObject = mapper.readValue(response.getEntity().getContent(), MyObject.Class);
if(myObject.getFunctions().isEmpty()){
throw new EmptyResultException("Empty result");
}
return myObject;
}
My EmptyResultException
Class :
@ResponseStatus(value=HttpStatus.NO_CONTENT)
public Class EmptyResultException() extends RuntimeException(){
...
}
I'm just starting with JUnit and I have tried :
@Mock MyService myservice;
@Test(expected=EmptyResultException.class)
public void shouldReturnException() {
when(myService.queryDatabase(anyString(),anyString())).thenReturn(new MyObject());
}
It's not working. The behavior I want to try is in private
method. It seems I should use Powermock for such cases. However, I have read it is not good to test private
method so I would like to change my method to public
. Any help please?
EDIT : My full implementation :
I have a Restcontroller :
@RestController
@RequestMapping...
public class MyController {
@Autowired
MyService myService;
@RequestMapping...
public MyObject findObject(@Valid DtoParameters parameters){
return myService.executeQuery(parameters);
}
}
And in myService Class :
@Service
public class MyService{
public MyObject executeQuery(DtoParameters parameters){
return
queryDatabase(parameters.buildRequest(),parameters.buildEnd());
}
}
If your class under test is MyService
, it shouldn't have a @Mock
.
I don't know your whole implementation, but let's assume MyService
have injected dependencies (like your mapper
)
First I would mock the mapper and inject it in MyService
:
@Mock
private ObjectMapper mapper;
@InjectMocks
private MyService myService;
For this to work, your test class need to use the mockito runner. You can annotate your class with this:
@RunWith(MockitoJUnitRunner.class)
The mocks will be injected into MyService. Now you can mock your mapper to return an empty object:
when(mapper.readValue(any(),any())).thenReturn(new MyObject());
myService.queryDatabase("request", "end")
when calling queryDatabase, this should call the mock inside.
If you were trying to test your rest controller, it is a different way. What I suggested is a unit test on MyService. If you want to test the controller, you should do it with a SpringRunner
, SpringBootTest
and MockMvc
. But first, unit test your service, and add other tests on your controller later. For the controller, you would annotate MyService with @MockBean
and throw, or Autowire
it and @MockBean
the mapper inside to return an empty object like the unit test.
Check this: https://spring.io/guides/gs/testing-web/
old answer:
You could change your method to protected
, assuming your test is in the same package as the class you are testing, you will be able to mock it.
To mock your method, you need to write it like this:
when(myService.queryDatabase(anyString(),anyString())).thenThrow(EmptyResultException.class);
You forgot to use the when
method to wrap your call.