【发布时间】:2020-12-16 01:53:44
【问题描述】:
我在集成测试我的 SpringBoot 应用程序时遇到问题。
这是我测试类的基本结构:
@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;
}
}
如您所见,它依赖于两个存储库,它们是从 JpaRepository 扩展的接口和一个服务类。它们都是通过 lombok RequiredAllArgs-constructor 注入的。
在我的测试中,我正在与一个运行良好的 H2 数据库进行通信,并且我想模拟 pnSvc。
这是我的测试类:
@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());
}
}
不幸的是,模拟方法 pnSvc.sendAll(...) 返回 null,因此 MiddlemanResponse 列表为空,我的测试失败:
org.opentest4j.AssertionFailedError: expected: <1> but was: <0>
Expected :1
Actual :0
我的期望是被模拟的方法应该返回设置值List.of(new MiddlemanResponse(deviceToken, "response_message")。
解决方案
感谢 dbl 和 Gianluca Musa 的回复,我采用了 Gianluca Musa 的方法,即使用 any() 而不是传递实际参数
-> pnSvc.sendAll(any()) 模拟响应时
我也没有使用 Gianluca Musa 提出的org.mockito.Matchers.any
而是org.mockito.Mockito.any,因为它已弃用。
【问题讨论】:
-
Mocks 默认返回
null,除非您指定要返回的特定值... -
在
when(that.doThis(someVal).thenReturn(blah)的情况下,您应该使用匹配器...例如when(that.doThis(eq(someVal)).thenReturn(blah)
标签: java spring-boot integration-testing spring-boot-test