当前位置: 首页 > 知识库问答 >
问题:

如何在使用Mockito时清理spring测试中的Mock

容远
2023-03-14

我通过在@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(...);

}

共有1个答案

濮嘉茂
2023-03-14

>

  • 关于将重置放在测试方法之后

    我认为重置模拟最好在测试方法之后进行,因为这意味着在测试过程中确实发生了一些需要清理的事情。

    如果重置是在测试方法之前完成的,我会感到不确定,在应该重置的测试之前发生了什么?关于非模拟对象呢?有原因(也许有)吗?如果代码中没有提到它是有原因的(例如方法名)?等等。

    但是麻烦还在继续,测试应该快速而小,以便向开发人员提供快速的反馈(IDE插件如Infinitest对此很好),但是使用Spring的测试天生更慢,更消耗内存。这会减少运行它们的次数,甚至在本地工作站上完全避免它们...然后在CI服务器上发现它们失败了。

    使用Mockito和Spring的生命周期

    因此,当为子系统精心编制集成测试时,您最终会得到许多对象,显然还有合作者,这些对象可能会被嘲笑。生命周期由Spring Runner控制,但Mockito mocks不是。因此,您必须自己管理模拟生命周期。

    顺便说一句,有趣的是看到这个问题发生在JUnit上下文中,因为JUnit为每个测试方法实例化了测试类。如果测试基于TestNG,那么方法可能会有所不同,因为TestNG只创建测试类的一个实例,无论使用Spring,都必须休止模拟字段。

    老答:

    我不太喜欢在spring ConxText中使用Mockito mocks。但你会不会在找这样的东西:

    @After public void reset_mocks() {
        Mockito.reset(placeOrderService);
    }
    

  •  类似资料:
    • 我希望能够测试一条从队列中消耗的路由,然后在涉及spring注入服务的bean中进行一些工作,并使用mockito有效地模拟该服务。 我的Spring路线如下: emailService bean有一个自动连接的服务,然后在createEmailRequest()中调用该服务,该服务将转到另一个服务并检索用户数据以供后续使用。 测试: bean如下: 所有编译都正常,当运行路由时,队列上弹出一个对

    • 我有一个类需要进行单元测试: 我有一个测试用例: 当我运行测试用例时,没有使用ActiveMQConnectionFactory的模拟对象。相反,正在使用实际的实现,并且正在建立TCP连接: 我尝试了Powermockito和Mockito,但都失败了。如何模拟对象,如何成功运行测试用例? 我是单元测试新手,试图从各个社区获得帮助,但没有找到合适的答案。任何帮助都将不胜感激。谢谢

    • 我能够测试代码,但代码覆盖率不包括第二个开关情况。 请参考以下代码。 下面是我的测试代码。 由于我已经声明了一个带有测试值的字符串变量,所以我无法涵盖第二个switch语句。我尝试过if else的情况,但同样的问题发生了。我们还有别的办法吗?

    • 我有一个使用JSONObject的函数,我需要测试它。下面是我的代码: 这是我想测试的代码: 谢谢

    • 我有一个函数,在这个函数中,我想替换一些组件的行为(余弦,正弦,...),我正在尝试为这些部分创建一个mock,并将它们传递给函数。 问题是,我收到以下消息: *org.mockito.exceptions.misusing.MissingMethodInvocationException:当()需要一个必须是“模拟上的方法调用”的参数。例如:当(mock.getArticles()). then

    • 为了获得可重用和可测试的rxjava代码,我使用ObservableTransformers分离了代码的各个部分。它在生产中工作得很好,但是测试它并不像预期的那么容易,因为我似乎无法模拟那些观察到的ransformers。 when(observableTransformer.apply(any())).thenreturn(observable.just(“mockedtext”)); 一旦调用