与该模拟游戏的零交互

与该模拟游戏的零交互

本文介绍了Mockito:与该模拟游戏的零交互的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要测试的课程.

I have a class that I would like to test.

@Configuration
@Import(EmailageConfiguration.class)
public class EmailageServiceConfiguration {

    private static final String EMAILAGE_ACCOUNT_ID_CONFIG_KEY = "emailage.key";
    private static final String EMAILAGE_API_KEY_CONFIG_KEY = "emailage.secret";

    @Bean
    public EmailageConfigHolder emailageConfigHolder(Environment env) {

        final EmailageConfigHolder holder = new EmailageConfigHolder();

        holder.setApiKey(env.getRequiredProperty(EMAILAGE_API_KEY_CONFIG_KEY));
        holder.setAccountId(env.getRequiredProperty(EMAILAGE_ACCOUNT_ID_CONFIG_KEY));

        return holder;
    }

}

提供了我的测试课程,

@RunWith(MockitoJUnitRunner.class)
public class EmailageServiceConfigurationTest {

    @InjectMocks
    private EmailageServiceConfiguration configuration;

    @Mock
    private Environment environment;

    @Mock
    private EmailageConfigHolder holder;

    @Test
    public void testEmailageConfigHolder() {

        when(environment.getRequiredProperty(anyString())).thenReturn(anyString());

        configuration.emailageConfigHolder(environment);

        verify(holder, times(1)).setApiKey(anyString());
        verify(holder, times(1)).setAccountId(anyString());
    }
}

我得到下面提供的错误堆栈,

I get the error stack provided below,

我该如何更正测试?

推荐答案

此处:

final EmailageConfigHolder holder = new EmailageConfigHolder();

Mockito无法将模拟注入到 local 变量中. 文档确实是清楚一点:

Mockito can't inject mocks into a local variable. The documentation is really clear about that:

基本上,通过在方法正文中使用new(),您编写了难以测试的代码.因为使用Mockito,您具有选项来控制new()在该方法主体中返回的内容.

Basically, by using new() within the body of your method you wrote hard to test code. Because with Mockito, you have zero options to control what new() will return in that method body.

解决之道:

  • 将持有人"设置为您类的一个字段,然后通过该注释或通过接受持有人实例的构造函数进行注入
  • 将实例作为参数传递给方法

或者假设您可以在单元测试设置中的生产代码中实际创建一个新的Holder对象,并且在您返回该对象时,只需声明返回对象的属性.从这个角度来看,您根本不需要在这里使用模拟.只需验证从该调用返回的对象是否具有预期的属性即可!

Or assuming that you can actually create a new Holder object within the production code within your unit test setup, and as you are returning that object, simply assert on the properties of the returned object. From that point of view, you do not need to using mocking here at all. Simply verify that the object coming back from that call has the expected properties!

或者,(不建议)您可以使用PowerMock(ito)或JMockit,以获得对new()的调用的控制权.但是如前所述:更好地重新编写代码,使其易于测试.

Or, (not recommended) you could turn to PowerMock(ito) or JMockit, in order to gain control over that call to new(). But as said: better rework your code to be easy to test.

顺便说一句:真正的答案是您退后一步,阅读有关Mockito的出色教程.您无法通过反复试验来学习如何使用这样的框架.通过漂亮的小示例学习如何正确地做到这一点,然后,当您了解如何连接点之后,将其应用于您自己的代码!

By the way: the real answer is that you step back and read a good tutorial about Mockito. You can't learn how to use such a framework by trial and error. Learn how to do it right with nice small examples, and then, when you understand how to connect the dots, then apply that to your own code!

这篇关于Mockito:与该模拟游戏的零交互的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-04 23:42