1

I'm trying to call the second method of this class, and always get null. Note that it returns new User() however in the test class I always get null:

@Stateless
public class UserDAO2 {

    public Connection getConnFromPool(int i) {
        return null;
    }

    public User readByUserid(String s) {
        System.out.println("In DAO 2");
        Connection c = getConnFromPool(1);
        return new User();
    }
}

And the test class:

@RunWith(MockitoJUnitRunner.class)
public class UserBeanUnitTest {

    @InjectMocks
    private UserDAO2 dao2;

    @Before
    public void setup() {
        dao2 = Mockito.mock(UserDAO2.class);
        MockitoAnnotations.initMocks(this);
    }


    @Test
    public void testBean() {

        Mockito.when(dao2.getConnFromPool(1)).thenReturn(null);

        User expectedUser = new User();
        expectedUser.setSk(1);
        expectedUser.setFirstName("David");
        expectedUser.setLastName("Gahan");
        expectedUser.setUserid("user1");

        User user = dao2.readByUserid("user1"); // <-- this method always returns null

        assertThat(user).isEqualTo(expectedUser); // <-- test fails as expectedUser != null

    }

}

Also, note that System.out.println is never printed. How to fix this to actually make a call to dao.readByUserid() ?

ps0604
  • 1,227
  • 23
  • 133
  • 330

1 Answers1

1

If you need to test the method of some class, and inside of it the other method of the same class is called which you want to mock, then you need to use @Spy:

@RunWith(MockitoJUnitRunner.class)
public class UserDAO2Test {

    @InjectMocks
    @Spy
    private UserDAO2 dao;

    @Test
    public void testBean() {

        Mockito.doReturn(null).when(dao).getConnFromPool(1);

        User expectedUser = new User();
        expectedUser.setSk(1);
        expectedUser.setFirstName("David");
        expectedUser.setLastName("Gahan");
        expectedUser.setUserid("user1");

        User user = dao.readByUserid("user1");

        assertThat(user).isEqualTo(expectedUser);
    }
}

Note that I slightly modified the line with mocking getConnFromPool because it's required when you use that technique.

See docs for spying.

amseager
  • 5,795
  • 4
  • 24
  • 47
  • I do need to mock the class, as I need to do `Mockito.when(dao.getConnFromPool(1)).thenReturn(null);`. The question I posted is a simplification. – ps0604 Apr 10 '20 at 21:00
  • if you test `readByUserid` method then you don't need to mock `getConnFromPool` because it's not called in it. – amseager Apr 10 '20 at 21:11
  • In the real code it is called, I just didn't put it in the question. I adjusted the question to avoid any confusions. – ps0604 Apr 10 '20 at 21:12
  • Sorry, but `dao.readByUserid` still returns null, maybe the `@Stateless` annotation is creating the problem? – ps0604 Apr 10 '20 at 21:29
  • Very strange, `MockitoJUnitRunner` should ignore this annotation. Maybe something else is missing in the example from the question because I've tested this code and the test worked correctly. – amseager Apr 10 '20 at 21:34
  • The code is identical, it's what I put in the question, still get null. Not sure what could be the problem, I'm running this on Eclipse/JUnit 4 and the method always returns null. – ps0604 Apr 10 '20 at 21:44
  • I made an example: https://github.com/amseager/spytest. You could try it and then compare it with your code. Maybe we're missing something. – amseager Apr 10 '20 at 21:47
  • I just replaced the code and it worked, I don't know what was wrong with mine, I will build on top of your code – ps0604 Apr 10 '20 at 21:51
  • The difference with your code is that I had `MockitoAnnotations.initMocks(this);` I use this in other examples and it works fine, not sure why it creates a conflict here. – ps0604 Apr 10 '20 at 21:58