我有以下接口:
public interface SomeProcessor<T> {
void process(Stream<T> someStream);
default <R> R someMap(Function<T, R> function,
T message,
Logger log) {
try {
return function.apply(message);
} catch (Exception exception) {
log.error("Mapping error for message => {}", message, exception);
return null;
}
}
}
并希望通过模拟测试覆盖方法的日志部分,但不幸的是它总是失败。现在我有以下测试:
@ExtendWith(MockitoExtension.class)
class SomeProcessorTest<T> implements SomeProcessor<T> {
@Mock
private Logger mockLogger;
@Override
public void process(Stream<T> someStream) {
}
@Override
public <R> R someMap(Function<T, R> function, T message, Logger log) {
try {
return function.apply(message);
} catch (Exception exception) {
log.error("Mapping error for message => {}", message, exception);
return null;
}
}
@Test
void testWithException() {
SomeProcessor<String> processor = new SomeProcessor <String>() {
@Override
public void process(Stream<String> someStream) {
}
@Override
public <R> R someMap(Function<String, R> function, String message, Logger log) {
throw new RuntimeException("test exception");
}
};
Function<String, Integer> function = Integer::parseInt;
String message = "123";
assertThrows(RuntimeException.class, () -> processor.someMap(function, message, mockLogger));
ArgumentCaptor<String> someCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<Throwable> exceptionCaptor = ArgumentCaptor.forClass(Throwable.class);
verify(mockLogger).error(eq("Mapping error for message => {}"), eq(message), any(RuntimeException.class));
assertEquals("Mapping error for message => {}", someCaptor.getValue());
assertTrue(exceptionCaptor.getValue() instanceof RuntimeException);
}}
但是我总是看到与Wanted but not invoked: mockLogger.error...
相关的错误,并且我无法在我的接口中覆盖以下行
catch (Exception exception) {
log.error("Mapping error for message => {}", message, exception);
return null;
我应该如何修改我的模拟测试来覆盖这些行并且不捕获错误?请给予我一条建议。
1条答案
按热度按时间c6ubokkw1#
在你的代码中似乎有很多混淆的东西,乍一看,它背后的原理并不清楚。
mockLogger.error
没有被调用的问题的根源在于你在测试方法中从匿名类的接口重写了someMap
方法的默认实现:因此,您尝试测试的代码根本不会被调用,而是应该从匿名类调用
super.someMap(...)
来调用实际的接口方法默认实现。但是,当您这样做时,被抛出的
RuntimeException
的Assert将失败,因为原始方法消耗了异常并返回null
-没有抛出异常。删除抛出异常的Assert仍然不会使测试通过,因为您正在测试的函数(
Integer::parseInt
)对于您提供的message
应该可以正常工作(x 1m 7 n 1x),所以catch
块不会被执行,因为没有抛出异常。为了解决这个问题,你应该传递一个会导致解析失败的消息值-而不是一个数字(例如"abc"
)。最后-我不明白为什么你的类实现
SomeProcessor<T>
,但这似乎是多余的,可能会被删除。