使用 Mockito 验证使用包含子字符串的参数调用方法

bob*_*e01 5 java unit-testing mockito

logger.error被调用时,有很多不同的东西可以作为第三个参数传递。

如何验证e包含特定子字符串?

这是我的生产代码..

public class MyClass {

    private ILogger logger = Slf4jLogbackLogger
            .generateLogger(MyClass.class.getClassLoader().getResource("log_messages.properties"));

    public void doSomething() {
        logger.info(Optional.empty(), "MyClass.doSomething");

        try {
            .. do things // throw new RuntimeException("something");

        } catch (Exception e) {
            logger.error(Optional.empty(), "HANDLE_EXCEPTION", e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的测试代码..

@RunWith(MockitoJUnitRunner.class)
public class TestMyClass {

    @Mock
    private ILogger logger;

    @InjectMocks
    @Spy
    private MyClass myClass = new MyClass();

    @Before
    public void init() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testMyClass() throws Exception {

        try {
            myClass.doSomething();
        } catch (Exception e) {
            fail("Should not have thrown any exceptions");
        }
        Mockito.verify(logger, Mockito.times(1)).error(Optional.empty(), "HANDLE_EXCEPTION", "Contains something specific");
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我收到的错误..

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
3 matchers expected, 1 recorded:

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"));
Run Code Online (Sandbox Code Playgroud)

已经尝试过类似下面的事情,但同样的错误:

ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
Mockito.verify(logger, Mockito.times(1)).error(Optional.empty(), "HANDLE_EXCEPTION", argument.capture());
Run Code Online (Sandbox Code Playgroud)

mic*_*alk 6

error调用该方法期间的所有参数都logger需要符合matchers您的情况。matchers这是使用和模拟某些 Service 类的示例:

@ExtendWith(MockitoExtension.class)
public class SomeTestClass {

    private static class MyService {
        public void error(Optional<String> op, String msg1, String msg2) {

        }
    }

    @Test
    void testMethod() {
        MyService myService = Mockito.mock(MyService.class);
        myService.error(Optional.empty(), "This is error", "Some error appeared");
        Mockito.verify(myService, Mockito.times(1)).error(Mockito.any(), Mockito.eq("This is error"), Mockito.contains("error"));
    }
}
Run Code Online (Sandbox Code Playgroud)

这里Mockito.any(), Mockito.eq(),Mockito.contains()是返回匹配器的方法。

要断言该方法是在String包含给定子字符串的情况下调用的,请使用Mockito.contains()匹配器。在这里您可以找到有关使用Matchers的更多信息。