简体   繁体   中英

Testing RepositorSpring Boot Integration Test - mock returns null

I'm having trouble with integration testing my SpringBoot application.

This is the basic structure of my class under test:

@Controller
@RequiredArgsConstructor
public class PushNotificationController {
    private final PushNotificationService pnSvc;
    private final PushNotificationRepository pnRepo;
    private final DeviceTokenRepository dtRepo;

/**
 * This method sends all PushNotifications from memory,
 * which are not sent yet.
 */
public List<MiddlemanResponse> send() {
    List<MiddlemanResponse> middlemanResponses = pnSvc.sendAll(dtRepo.findBySendStatus(DeviceTokenEntity.Status.SCHEDULED));

    return middlemanResponses;
}

}

As you can see it depends on two repositories which are interfaces extending from JpaRepository and a Service-class. All of them are injected via lombok RequiredAllArgs-constructor.

Inside my test I am communicating with an H2 database which works fine and also I want to mock the pnSvc .

Here is my testclass:

@RunWith(SpringRunner.class)
@SpringBootTest
public class PushNotificationControllerIntegrationTest {
@Autowired
private PushNotificationController underTest;

@Autowired
private DeviceTokenRepository dtRepo;
@Autowired
private PushNotificationRepository pnRepo;
@MockBean //we mock this dependency because we dont want to send actual notifications
private PushNotificationService pnSvc;

//testvalues
private final Long FIRST_PUSH_NOTIFICATION_ID = 1L;
private final Long FIRST_DEVICE_TOKEN_ID = 1L;
PushNotificationEntity pushNotification = new PushNotificationEntity(FIRST_PUSH_NOTIFICATION_ID, "message", "customString", 1L, "metadata");
DeviceTokenEntity deviceToken = new DeviceTokenEntity(FIRST_DEVICE_TOKEN_ID, "deviceToken",  pushNotification, DeviceTokenEntity.Platform.IPHONE, "applicationType","brandId", DeviceTokenEntity.Status.SCHEDULED);

@Before
public void setUp() throws MiddlemanException {
    when(pnSvc.sendAll(dtRepo.findBySendStatus(DeviceTokenEntity.Status.SCHEDULED))).thenReturn(List.of(new MiddlemanResponse(deviceToken, "response_message")));

    pnRepo.save(pushNotification);
    dtRepo.save(deviceToken);
}

@Test
public void sendOneSuccessTest() {
    List<MiddlemanResponse> responses = underTest.send();

    assertEquals(1, responses.size());
}

}

Unfortunatly the mocked method pnSvc.sendAll(...) returns null , therefore the List of MiddlemanResponse is empty and my test fails with:

org.opentest4j.AssertionFailedError: expected: <1> but was: <0>
Expected :1
Actual   :0

My expectation is that the mocked method should return the set value List.of(new MiddlemanResponse(deviceToken, "response_message") .

SOLUTION Thanks to dbl and Gianluca Musa for your replies I went with Gianluca Musa's approach of using any() instead of passing an actual parameter -> pnSvc.sendAll(any()) when mocking the response

Also I did not use Gianluca Musa's proposed org.mockito.Matchers.any but rather org.mockito.Mockito.any because of its deprecaion.

大概错误是mock的filter不对,可以用一个泛型选择器来模拟sendAll(),试试这个

when(pnSvc.sendAll(org.mockito.Mockito.any()).thenReturn(List.of(new MiddlemanResponse(deviceToken, "response_message")));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM