我对 Mockito 很陌生,清理起来有些麻烦。
我曾经使用 JMock2 进行单元测试。据我所知,JMock2 将期望和其他模拟信息保留在将为每个测试方法重建的上下文中。因此,每种测试方法都不会受到其他方法的干扰。
在使用 JMock2 时,我对 spring 测试采用了相同的策略,我发现我在帖子中使用的策略存在潜在问题:为每种测试方法重建应用程序上下文,因此减慢了整个测试过程。
我注意到很多文章都推荐在春季测试中使用 Mockito,我想尝试一下。在我在测试用例中编写两个测试方法之前,它运行良好。每个测试方法单独运行时通过,如果它们一起运行,则其中一个失败。我推测这是因为模拟信息被保留在模拟本身中(因为我在 JMock 中没有看到任何类似的上下文对象)并且模拟(和应用程序上下文)在两种测试方法中都是共享的。
我通过在 @Before 方法中添加 reset() 来解决它。我的问题是处理这种情况的最佳做法是什么(reset() 的 javadoc 说如果你需要 reset(),代码是有味道的)?任何想法都值得赞赏,在此先感谢。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"file:src/main/webapp/WEB-INF/booking-servlet.xml",
"classpath:test-booking-servlet.xml" })
@WebAppConfiguration
public class PlaceOrderControllerIntegrationTests implements IntegrationTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Autowired
private PlaceOrderService placeOrderService;
@Before
public void setup() {
this.mockMvc = webAppContextSetup(this.wac).build();
reset(placeOrderService);// reset mock
}
@Test
public void fowardsToFoodSelectionViewAfterPendingOrderIsPlaced()
throws Exception {
final Address deliveryAddress = new AddressFixture().build();
final String deliveryTime = twoHoursLater();
final PendingOrder pendingOrder = new PendingOrderFixture()
.with(deliveryAddress).at(with(deliveryTime)).build();
when(placeOrderService.placeOrder(deliveryAddress, with(deliveryTime)))
.thenReturn(pendingOrder);
mockMvc.perform(...);
}
@Test
public void returnsToPlaceOrderViewWhenFailsToPlaceOrder() throws Exception {
final Address deliveryAddress = new AddressFixture().build();
final String deliveryTime = twoHoursLater();
final PendingOrder pendingOrder = new PendingOrderFixture()
.with(deliveryAddress).at(with(deliveryTime)).build();
NoAvailableRestaurantException noAvailableRestaurantException = new NoAvailableRestaurantException(
deliveryAddress, with(deliveryTime));
when(placeOrderService.placeOrder(deliveryAddress, with(deliveryTime)))
.thenThrow(noAvailableRestaurantException);
mockMvc.perform(...);
}