当 运行 作为 Gradlew 任务时,Mockito Spring 测试失败
Mockito Spring Test Fails When Run as a Gradlew Task
我有以下 class 来测试我的 spring 应用程序的工作。
此作业使用外部 API.
更新订单对象的状态
当我 运行 class 测试成功但是当我 运行 作为 gradlew 任务的一部分时(运行 多个集成测试,包括这个一)它失败了:
Wanted but not invoked:
client.updateOrder(
"o11111",
<Pending order update integration test$$ lambda$ 3 9 9/ 1 6 3 9 3 4 9 4 3 5>
);
-> at OrderUpdateIntegrationTest.shouldSendPendingOrderUpdatesSubmittedOrders(OrderUpdateIntegrationTest.java:77)
Actually, there were zero interactions with this mock.
测试class:
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = TestConfig.class)
@ExtendWith(value = {SpringExtension.class, MockitoExtension.class})
@ActiveProfiles("integration-test")
@DirtiesContext
public class OrderUpdateIntegrationTest {
private static final String ORDER_ID_1 = "o11111";
private static final String ORDER_ID_2 = "o22222";
static VerificationWithTimeout FIVE_SECOND_TIMEOUT = timeout(SECONDS.toMillis(5));
@Autowired
private TestScheduleConfigurer testScheduleConfigurer;
@MockBean
private OrdersClient client;
@MockBean
private UpdatePendingOrdersTasklet updateOrderAndSendEmail;
@MockBean
private UrlBuilder urlBuilder;
@Mock
private ResponseEntity<Order> mock200HttpResponse;
@Mock
private ResponseEntity<String> mockEmail200HttpResponse;
private Order order11111;
private Order order22222;
private OrderList ordersList = new OrderList();
@Test
public void shouldSendPendingOrderUpdatesSubmittedOrders() throws Exception {
order11111 = buildOrder(ORDER_ID_1);
order22222 = buildOrder(ORDER_ID_2);
ordersList.setItems(Arrays.asList(order11111, order22222));
when(client.getPendingOrdersObject(anyString())).thenReturn(ordersList);
when(client.updateOrder(any(String.class), any(Order.class))).thenReturn(mock200HttpResponse);
when(mock200HttpResponse.getStatusCode()).thenReturn(HttpStatus.OK);
when(updateOrderAndSendEmail.postSendEmail(any(JSONObject.class))).thenReturn(mockEmail200HttpResponse);
when(mockEmail200HttpResponse.getStatusCode()).thenReturn(HttpStatus.OK);
testScheduleConfigurer.triggerPendingOrderUpdateSchedule();
verify(client, FIVE_SECOND_TIMEOUT).updateOrder(eq(ORDER_ID_1), argThat(argument -> argument.getState().equals(OrderState.PROCESSING)));
verify(client, FIVE_SECOND_TIMEOUT).updateOrder(eq(ORDER_ID_2), argThat(argument -> argument.getState().equals(OrderState.PROCESSING)));
verify(urlBuilder, times(2)).buildComponent("emailNotifications");
}
private Order buildOrder(String orderId) {
Order order = new Order();
order.setId(orderId);
order.setSiteId("testSite");
order.setState(OrderState.SUBMITTED);
order.setLastModifiedDate("2019-10-20T01:02:03.004Z");
OrderShippingGroup shippingGroup = new OrderShippingGroup();
OrderAddress emailAddress = new OrderAddress();
emailaddress.setemail("test@test.test");
emailAddress.setFirstName("First Name");
emailAddress.setLastName("Last Name");
shippingGroup.setShippingAddress(emailAddress);
order.setShippingGroups(Arrays.asList(shippingGroup));
return order;
}
}
我认为问题是,当我只是 运行 测试时 @MockBean
标记会为上下文创建一个 OrdersClient
的新实例,所以当 when()
或 verify()
方法被调用,它按预期工作,但如果集成测试作为 gradlew 任务执行,作业可能使用与声明为 @MockBean
.[=19= 的实例不同的实例]
有没有办法在两种情况下使用同一个实例?如果这个假设是正确的。
如果不是,有什么问题?
谢谢,
佩德罗
updateOrder
方法缺少多个模型,因此它使用不同的应用程序配置进行归档。
我有以下 class 来测试我的 spring 应用程序的工作。
此作业使用外部 API.
更新订单对象的状态当我 运行 class 测试成功但是当我 运行 作为 gradlew 任务的一部分时(运行 多个集成测试,包括这个一)它失败了:
Wanted but not invoked:
client.updateOrder(
"o11111",
<Pending order update integration test$$ lambda$ 3 9 9/ 1 6 3 9 3 4 9 4 3 5>
);
-> at OrderUpdateIntegrationTest.shouldSendPendingOrderUpdatesSubmittedOrders(OrderUpdateIntegrationTest.java:77)
Actually, there were zero interactions with this mock.
测试class:
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = TestConfig.class)
@ExtendWith(value = {SpringExtension.class, MockitoExtension.class})
@ActiveProfiles("integration-test")
@DirtiesContext
public class OrderUpdateIntegrationTest {
private static final String ORDER_ID_1 = "o11111";
private static final String ORDER_ID_2 = "o22222";
static VerificationWithTimeout FIVE_SECOND_TIMEOUT = timeout(SECONDS.toMillis(5));
@Autowired
private TestScheduleConfigurer testScheduleConfigurer;
@MockBean
private OrdersClient client;
@MockBean
private UpdatePendingOrdersTasklet updateOrderAndSendEmail;
@MockBean
private UrlBuilder urlBuilder;
@Mock
private ResponseEntity<Order> mock200HttpResponse;
@Mock
private ResponseEntity<String> mockEmail200HttpResponse;
private Order order11111;
private Order order22222;
private OrderList ordersList = new OrderList();
@Test
public void shouldSendPendingOrderUpdatesSubmittedOrders() throws Exception {
order11111 = buildOrder(ORDER_ID_1);
order22222 = buildOrder(ORDER_ID_2);
ordersList.setItems(Arrays.asList(order11111, order22222));
when(client.getPendingOrdersObject(anyString())).thenReturn(ordersList);
when(client.updateOrder(any(String.class), any(Order.class))).thenReturn(mock200HttpResponse);
when(mock200HttpResponse.getStatusCode()).thenReturn(HttpStatus.OK);
when(updateOrderAndSendEmail.postSendEmail(any(JSONObject.class))).thenReturn(mockEmail200HttpResponse);
when(mockEmail200HttpResponse.getStatusCode()).thenReturn(HttpStatus.OK);
testScheduleConfigurer.triggerPendingOrderUpdateSchedule();
verify(client, FIVE_SECOND_TIMEOUT).updateOrder(eq(ORDER_ID_1), argThat(argument -> argument.getState().equals(OrderState.PROCESSING)));
verify(client, FIVE_SECOND_TIMEOUT).updateOrder(eq(ORDER_ID_2), argThat(argument -> argument.getState().equals(OrderState.PROCESSING)));
verify(urlBuilder, times(2)).buildComponent("emailNotifications");
}
private Order buildOrder(String orderId) {
Order order = new Order();
order.setId(orderId);
order.setSiteId("testSite");
order.setState(OrderState.SUBMITTED);
order.setLastModifiedDate("2019-10-20T01:02:03.004Z");
OrderShippingGroup shippingGroup = new OrderShippingGroup();
OrderAddress emailAddress = new OrderAddress();
emailaddress.setemail("test@test.test");
emailAddress.setFirstName("First Name");
emailAddress.setLastName("Last Name");
shippingGroup.setShippingAddress(emailAddress);
order.setShippingGroups(Arrays.asList(shippingGroup));
return order;
}
}
我认为问题是,当我只是 运行 测试时 @MockBean
标记会为上下文创建一个 OrdersClient
的新实例,所以当 when()
或 verify()
方法被调用,它按预期工作,但如果集成测试作为 gradlew 任务执行,作业可能使用与声明为 @MockBean
.[=19= 的实例不同的实例]
有没有办法在两种情况下使用同一个实例?如果这个假设是正确的。 如果不是,有什么问题?
谢谢, 佩德罗
updateOrder
方法缺少多个模型,因此它使用不同的应用程序配置进行归档。