Mockito: Zero interactions with this mock

廉价感情. 提交于 2019-12-24 12:34:09

问题


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;
    }

}

My test class is provided,

@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,

Wanted but not invoked: holder.setApiKey(); -> at com.ratepay.ella.service.config.EmailageServiceConfigurationTest.testEmailageConfigHolder(EmailageServiceConfigurationTest.java:48) Actually, there were zero interactions with this mock. Wanted but not invoked: holder.setApiKey(); -> at com.ratepay.ella.service.config.EmailageServiceConfigurationTest.testEmailageConfigHolder(EmailageServiceConfigurationTest.java:48) Actually, there were zero interactions with this mock. at com.ratepay.ella.service.config.EmailageServiceConfigurationTest.testEmailageConfigHolder(EmailageServiceConfigurationTest.java:48) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79) at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85) at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39) at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

How do I correct the test?


回答1:


Here:

final EmailageConfigHolder holder = new EmailageConfigHolder();

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

Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order and as described below.

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.

Ways out of that:

  • make that "holder" a field of your class, then inject via that annotation, or via a constructor accepting a holder instance
  • pass an instance as parameter to the method

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!

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.

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!




回答2:


While the other answer better fits with the situation, I'm not able to update the code and finally, wrote this test code.

@RunWith( MockitoJUnitRunner.class )
public class EmailageServiceConfigurationTest {

    private static final String ACCOUNT_ID = "emailage.key";
    private static final String API_KEY = "emailage.secret";

    @InjectMocks
    private EmailageServiceConfiguration configuration;

    @Mock
    private Environment environment;

    @Test
    public void testEmailageConfigHolder() {

        configuration.emailageConfigHolder( environment );

        verify( environment, times( 1 ) ).getRequiredProperty( API_KEY );
        verify( environment, times( 1 ) ).getRequiredProperty( ACCOUNT_ID );
    }
}


来源:https://stackoverflow.com/questions/56750066/mockito-zero-interactions-with-this-mock

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!