将 mokito.when 用于带有字符串和 Class<T> 参数的方法

Using mokito.when for method with String and Class<T> arguments

我有一个方法,我想创建一些单元测试(这个方法变形

applicationContext.getEnvironment().getProperty(key, class)

领事整合)

长话短说:

public class DynamicProperties {

 public <T> T getEnvironmentProperty(String key, Class<T> cls) {
        return cls.cast(applicationContext.getEnvironment().getProperty(key,cls));
    }
}

在测试其他一些使用 DynamicProperties class 的 class 时,如下所示:

   @Test
    void testA() {
        //before
        when(dynamicProperties.getEnvironmentProperty(eq(KEY_A), Boolean.class)).thenReturn(true);
        when(dynamicProperties.getEnvironmentProperty(eq(KEY_B), Long.class)).thenReturn(0l);

        //when
        archivedSensorsService.testMethod();

        //than
        verify(...)
    }

KEY_A KEY_B 是 public 静态最终字符串 我收到以下错误:

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

尝试以下操作时:

 @Test
        void testA() {
            //before
            when(dynamicProperties.getEnvironmentProperty(eq(KEY_A), anyObject())).thenReturn(true);
            when(dynamicProperties.getEnvironmentProperty(eq(KEY_B), anyObject())).thenReturn(0l);
    
            //when
            archivedSensorsService.testMethod();
    
            //than
            verify(...)
        }

出现以下错误:

org.mockito.exceptions.misusing.PotentialStubbingProblem: 
Strict stubbing argument mismatch. Please check:
 - this invocation of 'getEnvironmentProperty' method:
    dynamicProperties.getEnvironmentProperty(
    null,
    null
);
    -> at com.xxx.xxx ionNotBeenTriggered(..)
 - has following stubbing(s) with different arguments:
    1. dynamicProperties.getEnvironmentProperty(
    null,
    null
);

有什么建议吗?

问题是由于混合使用和不使用参数匹配器进行模拟引起的。如果您对其中一个模拟方法参数使用参数匹配器,则必须对所有参数使用匹配器。您可以阅读更多 here.

我创建了一个简单的 project on GitHub 解决方案 - 如果您愿意,可以查看它,但这里是代码片段:

@Test
void withoutEq() {
    DynamicProperties dynamicProperties = mock(DynamicProperties.class);
    when(dynamicProperties.getEnvironmentProperty(KEY_A, Boolean.class))
            .thenReturn(true);
    when(dynamicProperties.getEnvironmentProperty(KEY_B, Long.class))
            .thenReturn(1L);

    assertAll(
            () -> assertTrue(dynamicProperties.getEnvironmentProperty(KEY_A, Boolean.class)),
            () -> assertEquals(1, dynamicProperties.getEnvironmentProperty(KEY_B, Long.class))
    );
}

@Test
void withEq() {
    DynamicProperties dynamicProperties = mock(DynamicProperties.class);
    when(dynamicProperties.getEnvironmentProperty(eq(KEY_A), eq(Boolean.class)))
            .thenReturn(true);
    when(dynamicProperties.getEnvironmentProperty(eq(KEY_B), eq(Long.class)))
            .thenReturn(1L);

    assertAll(
            () -> assertTrue(dynamicProperties.getEnvironmentProperty(KEY_A, Boolean.class)),
            () -> assertEquals(1, dynamicProperties.getEnvironmentProperty(KEY_B, Long.class))
    );
}

如您所见 - 其中一种方法对方法的两个参数都使用 eq 匹配器,而另一种方法使用 none。两个测试都通过了。

你的情况

when(dynamicProperties.getEnvironmentProperty(eq(KEY_A), anyObject())).thenReturn(true);

这个 mock 没有导致“matcher combined with raw values”错误,因为 eqanyObject 都是参数匹配器,但是

when(dynamicProperties.getEnvironmentProperty(eq(KEY_A), Boolean.class)).thenReturn(true);

有一个匹配器 (eq) 和一个简单对象 (Boolean.class 没有 eq)。