Nullpointerexception EasyMock when testing Controller - java

I want to test my controller class and its methods.
My Controller method looks like this:
#RequestMapping(value = "/updateUserStory/{usid}", method = RequestMethod.GET)
public String updateUserStory(#PathVariable("trrid") Integer trrID, #PathVariable("usid") Integer userstoryID, Model model ){
UserStory userStory = this.userStoryService.getUserStoryById(userstoryID);
model.addAttribute("userstory", userStory);
model.addAttribute("trrID", trrID);
return "updateUserStory";
}
My test method looks like this:
public void updateUserStory() throws Exception {
Model model = mockModel();
UserStory userStory = new UserStory();
userStory.setId(1);
EasyMock.expect(userStoryService.getUserStoryById(1)).andReturn(userStory);
EasyMock.replay(userStoryService);
String test = controller.updateUserStory(1, 1, model );
EasyMock.verify(userStoryService);
Assert.assertEquals("updateUserStory", test);
}
I added #Mock above for the userStoryService
#Mock
private UserStoryServiceImpl userStoryService;
and #TestSubject for the UserStoryController (In the test simply called controller).
#TestSubject
UserStoryController controller = new UserStoryController();
When running the test I keep getting A NullPointerException at the EasyMock.expect line. I don't know how this is failing. I am mocking the right method.

I see two possible reasons.
1. You haven't used any runner or rule.
To inject mocks, EasyMock needs a JUnit rule
#Rule
public EasyMockRule mocks = new EasyMockRule(this);
or a runner
#RunWith(EasyMockRunner.class)
public class MyTest {
2. The field type is UserStoryService
Not UserStoryServiceImpl. So you should mock UserStoryService instead.

Related

Mockito - Unmocked method failed to return the object itself

I have a Spring #RestController that has a field of Apache Camel interface FluentProducerTemplate.
I am testing the controller with MockMvc and I am injecting FluentProducerTemplate as a mock.
I would like to mock only one method - request(), and use the real implementation of the other methods.
However, I get NullPointerException from the unmocked methods. Other FluentProducerTemplate methods n , their return type is FluentProducerTemplate. In the implementation they return this. The mock object returns null.
I thought that mockito #Mock mocks only the methods that I specify. Other methods use the original implementation. Is this a correct statement?
I tried #Spy instead of #Mock and I got the same error.
When I mock all the methods that I work with then it works and no NullPointerException.
Code:
REST Controller:
#RestController
#RequestMapping("/v1/test”)
public class MyController {
#EndpointInject(uri = "direct:main")
private FluentProducerTemplate producerTemplate;
#RequestMapping(value = “/test2”, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public MyResponse testRequest(
#RequestHeader(“id”) String id,
#RequestHeader(“context”) String context,
#RequestBody RequestBody requestBody
) {
MyResponse response = producerTemplate
.withHeader(“id”, id)
.withHeader(“context”, context)
.withBody(requestBody)
.request(MyResponse.class);
return response;
}
Test:
#RunWith(MockitoJUnitRunner.class)
public class MyControllerTest {
private MockMvc mockMvc;
#Mock
private FluentProducerTemplate producerTemplateMock;
#InjectMocks
private MyControllerTest myController;
private static MyResponse expectedResultSuccess;
private static String requestString;
private static HttpHeaders allRequestHeaders;
#BeforeClass
public static void setup() {
allRequestHeaders = new HttpHeaders();
allRequestHeaders.set(“id”, “123”);
allRequestHeaders.set(“context”, “ABCD1234”);
allRequestHeaders.set(“Content-Type”, “application/json”);
expectedResultSuccess = new MyResponse(“test”);
requestString = “request”BodyText;
}
#Before
public void init() {
mockMvc = MockMvcBuilders.standaloneSetup(myController).build();
when(producerTemplateMock.request(any())).thenReturn(expectedResultSuccess);
}
#Test
public void testSuccess() throws Exception {
mockMvc.perform(post(“/v1/test/test2)
.headers(allRequestHeaders)
.content(requestString))
.andExpect(status().isOk())
}
}
The test pass only when I add the below to init():
when(producerTemplateMock.withHeader(any(), any())).thenReturn(producerTemplateMock);
when(producerTemplateMock.withBody(any())).thenReturn(producerTemplateMock);
My main question is - why do I have to mock all methods?
I prefer to use the original implementation of withHeader() and withBody() and mock only request().
You want so called partial mocks. Depending on whether you want to set up mostly mocks or mostly call real implementations there are different prefered approaches.
1. spy for few mocks, mostly real implementation
If you want to mock only some methods and otherwise call the real implementation:
FluentProducerTemplate producerTemplateMock = spy(FluentProducerTemplate.class);
// Mock implementation
doReturn(expectedResultSuccess).when(producerTemplateMock).request(any());
// All other method call will use the real implementations
2. mock for mostly mocks, few real implementations
FluentProducerTemplate producerTemplateMock = mock(FluentProducerTemplate.class);
// Mock methods
when(producerTemplateMock.request(any())).thenReturn(expectedResultSuccess);
// tell mockito to call the real methods
when(producerTemplateMock.withHeader(any(), any())).thenCallRealMethod;
when(producerTemplateMock.withBody(any())).thenCallRealMethod();
As you can see, the 2nd approach is more boilerplate to write. However, it depends on your use case what approach is better suited.

How to Correctly mock an object with Mockito

I am trying to test the ClientDetails class below and trying to learn JUnit and Mockito at the same time.
// this is the class I'm trying to test
public class ClientDetails {
#Autowired private IApplicantService<Applicant> applicantService;
#Autowired private ClientDetailsHelpers helpers;
public FullClientDetails getClientDetails(String businessId, boolean isNewClient) {
FullClientDetails fcd = new FullClientDetails();
ClientParams params = new ClientParams();
params.setBusinessId(businessId);
ApplicantId ai = applicantService.retrieveApplicantIdFromBusinessId(params);
Long applicantId = ai.getApplicantId();
params.setApplicantId(applicantId);
Applicant applicant = applicantService.retrieveApplicantDetailsByHerdNumber(params);
helpers.validateRetrievedApplicant(applicant, isNewClient, businessId);
fcd.setApplicant(applicant);
// more method calls that get and assign objects to the fcd object
return fcd;
}
}
// ClientDetailsHelpers.java method that throws exception
public void validateRetrievedApplicant(Applicant applicant, boolean isNewClient, String businessId) {
if (applicant.getApplicantId() == null && !isNewClient) {
throw new ValidationSearchException(businessId);
}
}
// test class
#RunWith(MockitoJUnitRunner.class)
public class ClientDetailsTest {
private final static String BUSINESS_ID = "A1234567";
private final static Long APPLICANT_ID = null;
#InjectMocks
ClientDetails clientDetails;
#Mock ApplicantServiceImpl applicantService;
#Mock ClientDetailsHelpers helpers;
private ApplicantParams params;
private Applicant applicantWithInvalidId = new Applicant();
ApplicantId applicantId = new ApplicantId(APPLICANT_ID, BUSINESS_ID);
#Before
public void before(){
applicantWithInvalidId.setApplicantId(null);
}
#Test(expected = ValidationSearchException.class)
public void testGetFullApplicationDetails(){
when(applicantService.retrieveApplicantIdFromBusinessId(Mockito.any(ApplicantParams.class))).thenReturn(applicantId);
when(applicantService.retrieveApplicantDetailsByHerdNumber(Mockito.any(ApplicantParams.class))).thenReturn(applicantWithInvalidId);
FullClientDetails fcd = clientDetails.getFullClientDetails(BUSINESS_ID , false);
}
}
In my test class I create some mock objects, including an ApplicantId object to be returned when applicantService.retrieveApplicantIdFromBusinessId() is called and Applicant object with is applicantId attribute set to null to be return when applicantService.retrieveApplicantDetailsByHerdNumber() is called.
The function ClientDetailsHelper.validateRetrievedApplicant() should throw an exception if Applicant.getApplicantId() returns a null and if the boolean isNewClient is set to false however it doesn't seem to be happening in the test, it throws no exception and the #Test fails.
My best guess is that I am not using when().thenReturn() to correctly return the Applicant and ApplicantId objects I have created and instead another Applicant object is getting passed to validateRetrievedApplicant() and returning and applicantId of 0 when it gets to the validation method.
Any suggestions? Thanks!
Your code is not throwing an exception because there is nowhere in the code you are testing that throws that exception. I assume your exception is thrown within the ClientDetailsHelpers class but you are mocking this class so it will not call the actual code and so no exception will be thrown.
You need to think about what you want to test. Do you want to test the ClientDetails class in isolation as a unit? In which case you don't need to worry about the exception being thrown since its not part of the functionality of that class.
The second option is that you want to do more of an integration test where you pull in an actual ClientDetailsHelpers class but in order to do this you will need to include some configuration in your test to make sure that this bean is available to the test Spring context. You can do this using a Spring4JunitRunner instead of the Mockito one and then pulling in a configuration class with a component scan for your ClientDetailsHelpers class using the #ContextConfiguration(MyConfig.class) annotation on your test class where MyConfig is the relevant Spring config class.

how to mock an interface using PowerMockito in Java

req1(an object of request type 1)
req2(an object of request type 2)
class response{
public TxnResp txnResp(){
TxnResp txnResp = service.txn(req1 , req2);
return txnResp;
}
}
I am using Powermockito for mocking in my junit testing.
"txn" is an interface. I need to mock this line TxnResp txnResp = service.txn(req1 , req2); my test class. Because calling txn is returning some value's from the webservice, which are specified in the next line.
txnResp contains following values storeNo,retailerId and password. It has its own bean class, so that we can set values like txnResp.setStoreId(1);
Could any one please help me to mock the above interface 'txn' and return value to txnResp.
I am stuck for the last 5 hours in it. Any help will be highly appreciated.
In my opinion plain Mockito would be enough in your situation.
If service is a dependency that is injected (via constructor, setter i.e.), you could try something following:
public class ResponseTest{
#InjectMocks
private Response response;
#Mock
private Service serviceMock;
#Before
public void init(){
MockitoAnnotations.initMocks(this);
}
#Test
public void test(){
// Arrange
TxnResp txnResp = new TxnResp(...);
Mockito.doReturn(txnResp).when(serviceMock).txn(
Mockito.any(ReqType1.class), Mockito.any(ReqType2.class));
// Act and assert...
}
}

junit test case for spring MVC

we are developing an application using spring mvc framework. I have given all the classes below, please suggest how to write a junit test case for the below scenario.
I want to write a junit test case for the validateAccountInformation(requestDTO) method which is called in validateAccount(..) method of LPAValidator.java class. Below is my junit test case followed by the java classes. Actual call goes from the LPAController.java as shown in the below code.
LPAControllerTest.java
#Test(groups = "manual")
public void submitRequestForLPAAccountTest()
{
// businessCalendar.nextBusinessDay(
// LocalDateHelper.today(), LPAConstants.TWENTY_BUSSINESS_DAYS)
//i want to write the test case for the above commented logic,
//if business days is not equal to twenty days, test should fail.
}
LPAController.java
#RequestMapping(value = "/lpa/{accNumber}/spread, method = RequestMethod.GET)
public #ResponseBody LPAResponseDTO accountSearch(#RequestBody final LPARequestDTO clientrequestBody,
#PathVariable final String accNumber, final HttpServletResponse response)
{
//some logic goes here
final LPAAccountResponse domainResponse = service.submitRequestForLPAAccount(requestBody);
}
LPAServiceImpl.java
#PermitAll
#NonTransactional
public LPAResponse submitRequestForLPAAccount(final LPARequest requestDTO)
{
return lpaRepository.submitRequestForLPAAccount(requestDTO));
}
LPARepository.java
#PermitAll
#NonTransactional
public LPAResponse submitRequestForLPAAccount(final LPARequest requestDTO)
{
//some logic
lpaValidator.validateAccount(requestDTO);
//some logic
}
LPAValidator.java -- java class for validations
#component
class LPAValidator{
#Inject
private BusinessCalendar businessCalendar;
void validateAccount(final LPARequest requestDTO) throws Exception {
try {
validateAccountInformation(requestDTO);
} catch(Exception e){
}
}
private void validateAccountInformation(final LPARequest requestDTO) throws Exception{
final accDate lpaAccDate = requestDTO.getLPADate();
final LocalDate twentyBussinessDays = businessCalendar.nextBusinessDay(
LocalDateHelper.today(), LPAConstants.TWENTY_BUSSINESS_DAYS); //i want to write
//test case for this line of code, if business days given is more than twenty test should fail.
//some logic here
}
Please suggest what needs to be added in LPAControllerTest.java to test the nextBusinessDay(..) as discussed above.
You're trying to write an integration test in which your controller is called, which then calls all the subclasses until the validator is triggered. That is not a traditional 'unit test'.
A traditional unit test would just test the validator straight up, and nothing more.
Nevertheless, when writing an integration test, spring documentation to the rescue
In short, it'll require you to create an applicationcontext with all the necessary scaffolding, and then use a mockMvc call to do a GET on the created application.
If you want to test the validator, use simple mocking framework:
See [http://mockito.org]
Gives you something like this:
#Mock BusinessCalendar businessCalendarMock;
#Mock LPARequest mockRequest;
#Mock accDate mockDate;
#Mock LocalDate mockLocalDate;
#InjectMocks LPAValidator lpaValidator = new LPAValidator();
#Test public void testValidateAccount() {
when(mockRequest.getLPAdate()).thenReturn(mockDate);
when(businessCalendar.nextBusinessDay(LocalDateHelper.today(),LPAConstants.TWENTY_BUSSINESS_DAYS).thenReturn(mockLocalDate);
// continue your test from here
lpaValidator.validateAccount( mockRequest);
verify(businessCalendar).nextBusinessDay(LocalDateHelper.today(),LPAConstants.TWENTY_BUSSINESS_DAYS);
// although if the use of mockLocalDate is integral to your code, it'll probably show before and no verify is necessary;

how to unit test method using "Spring Data JPA" Specifications

I was playing with org.springframework.data.jpa.domain.Specifications, it's just a basic search :
public Optional<List<Article>> rechercheArticle(String code, String libelle) {
List<Article> result = null;
if(StringUtils.isNotEmpty(code) && StringUtils.isNotEmpty(libelle)){
result = articleRepository.findAll(Specifications.where(ArticleSpecifications.egaliteCode(code)).and(ArticleSpecifications.egaliteLibelle(libelle)));
}else{
if(StringUtils.isNotEmpty(code)){
result= articleRepository.findAll(Specifications.where(ArticleSpecifications.egaliteCode(code)));
}else{
result = articleRepository.findAll(Specifications.where(ArticleSpecifications.egaliteLibelle(libelle)));
}
}
if(result.isEmpty()){
return Optional.empty();
}else{
return Optional.of(result);
}
}
And that's actually working fine but I'd like to write unit tests for this method and I can't figure out how to check specifications passed to my articleRepository.findAll()
At the moment my unit test looks like :
#Test
public void rechercheArticle_okTousCriteres() throws FacturationServiceException {
String code = "code";
String libelle = "libelle";
List<Article> articles = new ArrayList<>();
Article a1 = new Article();
articles.add(a1);
Mockito.when(articleRepository.findAll(Mockito.any(Specifications.class))).thenReturn(articles);
Optional<List<Article>> result = articleManager.rechercheArticle(code, libelle);
Assert.assertTrue(result.isPresent());
//ArgumentCaptor<Specifications> argument = ArgumentCaptor.forClass(Specifications.class);
Mockito.verify(articleRepository).findAll(Specifications.where(ArticleSpecifications.egaliteCode(code)).and(ArticleSpecifications.egaliteLibelle(libelle)));
//argument.getValue().toPredicate(root, query, builder);
}
Any idea?
I was having almost the same problems as you had, and I changed my class that contains Specifications to be an object instead of just one class with static methods. This way I can easily mock it, use dependency injection to pass it, and test which methods were called (without using PowerMockito to mock static methods).
If you wanna do like I did, I recommend you to test the correctness of specifications with integration tests, and for the rest, just if the right method was called.
For example:
public class CdrSpecs {
public Specification<Cdr> calledBetween(LocalDateTime start, LocalDateTime end) {
return (root, query, cb) -> cb.between(root.get(Cdr_.callDate), start, end);
}
}
Then you have an integration test for this method, which will test whether the method is right or not:
#RunWith(SpringRunner.class)
#DataJpaTest
#Sql("/cdr-test-data.sql")
public class CdrIntegrationTest {
#Autowired
private CdrRepository cdrRepository;
private CdrSpecs specs = new CdrSpecs();
#Test
public void findByPeriod() throws Exception {
LocalDateTime today = LocalDateTime.now();
LocalDateTime firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
LocalDateTime lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
List<Cdr> cdrList = cdrRepository.findAll(specs.calledBetween(firstDayOfMonth, lastDayOfMonth));
assertThat(cdrList).isNotEmpty().hasSize(2);
}
And now when you wanna unit test other components, you can test like this, for example:
#RunWith(JUnit4.class)
public class CdrSearchServiceTest {
#Mock
private CdrSpecs specs;
#Mock
private CdrRepository repo;
private CdrSearchService searchService;
#Before
public void setUp() throws Exception {
initMocks(this);
searchService = new CdrSearchService(repo, specs);
}
#Test
public void testSearch() throws Exception {
// some code here that interact with searchService
verify(specs).calledBetween(any(LocalDateTime.class), any(LocalDateTime.class));
// and you can verify any other method of specs that should have been called
}
And of course, inside the Service you can still use the where and and static methods of Specifications class.
I hope this can help you.
If you are writing Unit Tests then you should probably mock the call to findAll() method of articleRepository Class using a mocking framework like Mockito or PowerMock.
There is a method verify() using which you can check if the mock is invoked for the particular parameters.
For Example, if you are mocking the findAll() method of articleRepository Class and want to know if this method is called with particular arguments then you can do something like:
Mokito.verify(mymock, Mockito.times(1)).findAll(/* Provide Arguments */);
This will fail the test if mock has not been called for the arguments that you provided.
Your problem is that you are doing too many things within that one method. You should have three different methods that work on articleRepository.
Then you can use mocking as the others suggest:
setup your mocks so that you know which call on articleRepository should be made
verify that exactly the expected calls are happening
Please note: these three methods should be internal; the main point there is: you can't test this method with ONE call from the outside; as it is doing more than one thing, depending on the input that you provide. Thus you need to create at least one test method for each of the potential paths in your code. And that becomes easier (from a conceptual point of view) when you separate your code into different methods.

Categories

Resources