【问题标题】:Make a class to be a Mockito mock without calling mock让一个类成为一个 Mockito 模拟而不调用模拟
【发布时间】:2015-08-31 14:13:36
【问题描述】:

我有一个使用服务的基于 Spring 的 Java 应用程序。对于some reasons,我需要自动装配一个仅为单元测试而实施的服务。我希望这个自动装配的类成为一个 Mockito 模拟,这样我就可以将它传递给所有 Mockito 方法(when() 等)。我应该扩展或实现一些 Mockito 类吗?

例如

@Profile("test")
@Primary
@Service
public class MockAService implements AService {
    public void callMethod(){}
}

那么在测试中我有

{
    System.setProperty("spring.profiles.active", "test");
}

@Autowired AService aservice;

在我想做的测试方法中:

@Test
public void test(){
  doNothing().when(aService).callMethod();
}

【问题讨论】:

  • 您可能可以使用 bean 覆盖并为您的测试定义一个额外的上下文,并使用 @ContextConfiguration 将其与原始应用程序上下文合并

标签: java spring unit-testing mockito


【解决方案1】:

只需使用@Spy 并在您的@Before 方法中调用MockitoAnnotations.initMocks。它将为您注入的服务创建一个间谍。

示例我想测试 MyService,它依赖于 MyDao。我希望 MyService 使用我模拟的 dao。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/com/stackoverflow/mokito/exemple/spring.xml"})
public class TestCase {
    @Resource
    @InjectMocks
    private MyService service;

    @Resource
    @Spy
    private MyDao dao;

    public void setup() {
        MockitoAnnotations.initMocks(this);
    }
}

但是,您的 spring 上下文现在是“脏的”。下一个测试类将使用相同的 spring 上下文,而 MyService 仍将使用 mock。所以不要忘记在@After 中重置模拟

【讨论】:

  • 但是 spy 是如何进入 Spring 应用程序上下文以用于连接的呢?
  • 不会的。在其他有线对象上使用 @InjectMock 来使用它而不是“真实”对象
  • @JEY 为什么你建议使用间谍而不是模拟? Mock 也可以在接口上创建(SpaceTrucker 中的 AService 问题)
  • 我建议使用 SPY,因为在大多数情况下,您不想更改整个组件的行为。
【解决方案2】:

如果您不希望服务做任何事情,模拟甚至比间谍更好。默认情况下,在模拟上调用函数不会做任何事情。 使用间谍,您必须显式调用 doNothing()。

但是你为什么要加载任何 Spring 上下文呢?您不能模拟所有服务并完全隔离地测试您的课程吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多