0

I'm new to unit testing and try to understand how mocking works. I got the code as below, where I mock PdRequest.class using PowerMockRunner. However, it return Null for all the variables. I also tried to set the value manually but its the same. Is there anything that I missing? and Is it better if I just create new PdRequest() and set all the values manually?

What I tried -Try to use @PrepareForTest and @ExtendWith -Try to put initMocks(this)

@RunWith(PowerMockRunner.class)
public class PerformanceServiceImplTest 
 PdRequest pdRequest = mock(PdRequest.class);
        when(pdRequest.getLoginUserId()).thenReturn("42");
        when(pdRequest.getYear()).thenReturn("Year");
        doNothing().when(pdRequest).setLoginUserId((String) any());
        doNothing().when(pdRequest).setCurrMetric((String) any());
        doNothing().when(pdRequest).setCurrentLink((BreadCrumLink) any());
        doNothing().when(pdRequest).setFullView((String) any());
        doNothing().when(pdRequest).setManagerId((String) any());
        doNothing().when(pdRequest).setMetric((String) any());
        doNothing().when(pdRequest).setPdBoard((String) any());
        doNothing().when(pdRequest).setRegionId((String) any());
        doNothing().when(pdRequest).setRoleId((String) any());
        doNothing().when(pdRequest).setRoleLevel((Integer) any());
        doNothing().when(pdRequest).setRoleName((String) any());
        doNothing().when(pdRequest).setSalesAbf((String) any());
        doNothing().when(pdRequest).setSalesMm((String) any());
        doNothing().when(pdRequest).setSalesRsme((String) any());
        doNothing().when(pdRequest).setStaffId((String) any());
        doNothing().when(pdRequest).setStaffIdList((List<String>) any());
        doNothing().when(pdRequest).setTeamId((String) any());
        doNothing().when(pdRequest).setYear((String) any());
        pdRequest.setCurrMetric("Curr Metric");
        pdRequest.setCurrentLink(breadCrumLink);
        pdRequest.setFullView("Full View");
        pdRequest.setLoginUserId("42");
        pdRequest.setManagerId("42");
        pdRequest.setMetric("Metric");
        pdRequest.setPdBoard("Pd Board");
        pdRequest.setRegionId("us-east-2");
        pdRequest.setRoleId("42");
        pdRequest.setRoleLevel(1);
        pdRequest.setRoleName("Role Name");
        pdRequest.setSalesAbf("Sales Abf");
        pdRequest.setSalesMm("Sales Mm");
        pdRequest.setSalesRsme("Sales Rsme");
        pdRequest.setStaffId("42");
        pdRequest.setStaffIdList(new ArrayList<>());
        pdRequest.setTeamId("42");
        pdRequest.setYear("Year");

Output Debugging object

anggor
  • 79
  • 1
  • 10
  • My recommendation: if you are new to testing, avoid Mockito. Write tests with plain Java. After you've become comfortable with writing basic tests, you can start learning Mockito. It is absolutely possible to write tests without Mockito (and often leads to better-designed classes) – knittl Jan 13 '23 at 17:48

2 Answers2

0

Ignore what IntelliJ is showing you. That shows you the state, which is inherited from the class you're mocking. However, you haven't set that state in the mock, and that state is not returned when any method is called. Instead, you've configured the Mockito internal fields (CGLIB$BOUND etc.) to return those values.

Rob Spoor
  • 6,186
  • 1
  • 19
  • 20
  • is the state you mentioned is ```when().thenReturn()```? – anggor Jan 13 '23 at 20:13
  • The state of any object is the collection of all its fields and their values. Because you set values on a mock, the actual fields are not set - the setters are intercepted by the mock's internal mechanisms. If you want an object that has its fields set, use `spy(new PdRequest())` instead of `mock(PdRequest.class)`. – Rob Spoor Jan 14 '23 at 11:38
0

I found a way of getting the value. From https://www.toptal.com/java/a-guide-to-everyday-mockito .

        PdRequest pdRequest = mock(PdRequest.class);
        doAnswer(InvocationOnMock::callRealMethod).when(pdRequest).setLoginUserId("42");
        doAnswer(InvocationOnMock::callRealMethod).when(pdRequest).getLoginUserId();
        pdRequest.setLoginUserId("42");
        assertEquals("42", pdRequest.getLoginUserId());
anggor
  • 79
  • 1
  • 10
  • One question: you tell your mock to call the real method for every method. Why not use the real thing in the first place? A lot simpler than going through a mock. Can't you simply do `PdRequest pdRequest = new PdRequest()` and be done? – knittl Jan 13 '23 at 21:55
  • yes, that is much easier to do. But as I said in the question, I try to understand how the mocking works and how to write it. that's why I insist to use ```mock()```. – anggor Jan 14 '23 at 02:22
  • But you are not really mocking nor stubbing. You have a "mock" that does "nothing" for a lot of methods and delegates to the real class for 2 methods. – knittl Jan 14 '23 at 08:29
  • The code in the question was written using ```diffblue cover``` extension from IntelliJ. Sorry for the confusion there. – anggor Jan 14 '23 at 09:10