4

I am supposed to mock a repository written by someone else.

I have an interface IUserDetailsRepository that just Queries the database to retrieve user details(finduser()) stored in it manually( not through create user method). The method finduser() is implemented in helper class and is used by service class. This class has getuser() method in which finduser() is called. How do I mock this? Should I mock service class and call getuser() or do I have to mock helper class and called finduser() method of repository?

I am stuck with this.. since I don't have createuser how do I mock the object and inject. I am totally confused. Please help me.

If any such programming structure is explained on how to mock, that would be of great help.

Here are the codes

 **********IUserDetails Repository************ @Repository public interface IUserDetails extends PagingAndSortingRepository<UserEntity,String> { @Query("select ud.id,ud.name,ud.unit from UserEntity u where ud.id=:id and ud.passwd=:passwd") List<Object[]> findUserbyID(@Param("id") String id, @Param("passwd") String passwd); } *****UserHelper class***** @Component public class UserHelper{ @Autowired private IUserDetails repo; @Transactional(rollbackFor=(Exception.class); @ExceptionHandler(Exception.class) publib List<UserDetailsDTO> findUserbyID(String id, String passwd) { List<UserDetailsDTO> user=new ArrayList<UserDetailsDTO>(); List<Object[]> repouser=repo.findUserbyID(id,passwd); UserDetailsDTO udto=new UserDetailsDTO(); for(Object[] ob:repouser) { udto.setid((String)ob[0])); udto.setname((String)ob[1])); udto.setunit((String)ob[2])); user.add(udto); } return user; } *********UserDetailsDTO ******** public class UserDetailsDTO implements Serializable{ private String id,name,unit,passwd; public String setid(String id) {this.id=id;} public String setpasswd(String passwd) {this.passwd=passwd;} public String setname(String name) {this.name=name;} public String setunit(String unit) {this.unit=unit;} public String getid() {return id;} public String getname() {return name;} public String getunit() {return unit;} public String getpasswd() {return passwd;} } *********UserDetailsService******** public class UserDetailsService{ @Autowired private UserHelper helper; public List<UserDetailsDTO> getUser(@PathVariable("id") String id, @PathVariable("passwd") String passwd) { List<UserDetailsDTO> udto=new ArrayList<UserDetailsDTO>(); udto=helper.findUserbyID(id,passwd); if(udto==null) throw new UserNotFound(id); return udto; } } ************Test class********** Importing junit and mockito related packages; @RunWith(MockitoJUnitRunner.class) public class UserDetailsTest{ @InjectMocks UserDetailsService service; @Mock IUserDetails rep; @Before public void setUp() { MockitoAnnotations.initMocks(this); } @Test public void TestFindUser() { UserDetailsDTO details=new UserDetailsDTO(); detail.setid("123"); details.setpasswd("p@wd"); details.sename("MyName"); details.setunit("Engg"); Mockito.when(rep.findUserbyId("123","p@wd")).thenReturn(details); // Throws me error related to mismatch return types //when i change it to thenReturn((List<Object[]>)details), it throws error that it is not able to stub List<UserDetailsDTO> ud=serrvice.getUser("123","p@wd"); asserThat(ud,is(notNullValue())); assertEquals(ud,details); } } 
2
  • Probably adding some code with actual method signatures will simplify others understanding your problem Commented Feb 25, 2017 at 2:34
  • Hi @SergGr , I edited my post and added the code. Also added my test code Commented Feb 25, 2017 at 3:54

1 Answer 1

2

From the UserDetailsService perspective, you do not need to mock the IUserDetails, but UserHelper:

public class UserDetailsTest{ @InjectMocks UserDetailsService service; @Mock UserHelper helperMock; @Before public void setUp() { MockitoAnnotations.initMocks(this); } @Test public void TestFindUser() { UserDetailsDTO details=new UserDetailsDTO(); detail.setid("123"); details.setpasswd("p@wd"); details.sename("MyName"); details.setunit("Engg"); List<UserDetailsDTO> userList = new ArrayList<>(); userList.add(details); Mockito.when(helperMock.findUserbyID("123","p@wd")).thenReturn(userList); List<UserDetailsDTO> resultUserList=serrvice.getUser("123","p@wd"); asserThat(ud,is(notNullValue())); assertThat("Size", userList.size(), equalTo(resultUserList.size()); assertEquals("Details",details, equalTo(resultUserList.get(0))); } 

The scenario that you were trying to achieve would have its place in the UserHelper test class:

 public class UserHelperTest{ @InjectMocks UserHelper userHelper; @Mock IUSerDetails repo; @Before public void setUp() { MockitoAnnotations.initMocks(this); } @Test public void shouldFindUserById() { String id = "id"; String name = "name"; String unit = "unit"; String passwd = ""passwd"; List<Object[]> queryResult = new ArrayList<>(); queryResult.add(new Object[]{id,name,unit}); Mockito.when(repo.findUserByID(id,passwd)).thenReturn(queryResult)); List<UserDetailsDTO> resultList = userHelper.findUserbyID(id,passwd); // assertions on size and content of first element.. 
Sign up to request clarification or add additional context in comments.

8 Comments

Thank You.. This is a great help. Will try to work on this. If you can further explain a little on why you have written mock on class and interface in two different classes that will help me.
You can mock an interface or a class. And i have split the tests because you should not invoke code of direct dependencies.. thats why i mock UserHelper from the Service test.. i does not care what is inside of UserHelper (which uses the Repo interface).. the Repo would be important only for the UserHelper class. Hope that helps
Hint: there is no need to use @Before with MockitoAnnotations.initMocks(this) when you are already using the mockito runner. Either runner or initMocks(); both do the same thing!
I am again getting the same error as before at thenReturn(details) as the method thenReturn(List<UserDetailsDTO>) in the type OngoingStubbing <List<UserDetailsDTO>> is not applicable for arguments (UserDetailsDTO). I in fact tried casting the type to List<userDetailsDTO>, this gives me a new error. "Unfinished stubbing detected here:"
Ok i got it.. I passed userList to theReturn() instead of details and it worked
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.