我正在尝试测试这样的东西:
try {
logger.info("message");
//do something
} catch(Exception e) {
logger.error(errorMessage);
}
我知道捕获异常并不是一个好习惯,但是有一些遗留代码,没有时间进行重构。
所以,我编写了一个单元测试,以便在try块中抛出NullPointerException,但现在我不知道如何编写断言行(显然,单元测试必须一直失败)。 请注意我不能使用:
final Logger logger = LogManager.getLogger(AnaliticsService.class);
final Appender mockAppender = mock(Appender.class);
logger.addAppender(mockAppender);
final ArgumentCaptor<LoggingEvent> captor = ArgumentCaptor.forClass(LoggingEvent.class);
Log4jConfigHelper.getInstance().bufferConfiguration();
verify(mockAppender, times(x)).doAppend(captor.capture());
因为我不知道UT正在运行时会记录多少条消息。
答案 0 :(得分:0)
我编写了一个单元测试,以便在try块中抛出NullPointerException,但现在我不知道如何编写断言行(显然,单元测试必须一直失败)。
您不需要以这种方式检查异常。抛出异常的测试失败。
} catch(Exception e) {
logger.error(errorMessage, e);
throw e; // report the error to the test
}
注意:何时向测试框架抛出错误,它会记录/打印它,所以我怀疑你不需要首先捕获它。
答案 1 :(得分:0)
你应该尝试为LoggerFactory做一个模拟。
首先使用:
注释您的TestClass@RunWith(PowerMockRunner.class)
@PrepareForTest({YourController.class, LoggerFactory.class})
然后进行测试,调用所需的方法并解决错误:
@Test
public void testErrorLogging() throws Exception {
mockStatic(LoggerFactory.class);
Logger logger = mock(Logger.class);
when(LoggerFactory.getLogger(any(Class.class))).thenReturn(logger);
YourController controller = new YourController();
controller.someMethod();
verify(logger).error(anyString());
}
答案 2 :(得分:0)
日志消息是代码用户界面的一部分。执行计算的代码不应该假设日志消息可供用户使用的方式,日志消息的文本和语言,甚至消息是否以文本形式传递(而不是以图形方式传递)。因此,计算代码应委托给隐藏所有这些细节的相关记录器类(在UI /表示层中)。
如果计算代码仅要求关联的记录器符合接口,并使用依赖注入与记录器类关联,则很容易模拟记录器以检查计算代码是否已请求记录。
因此,如果要测试的代码是这样的::
public class MyService
{
private final MyServiceLogger logger;
MyService(MyServiceLogger logger)
{
this.logger = Objects.requireNonNull(logger);
}
public void processFile(Path path) {
...
try{
...
} catch (EOFException e) {
logger.logUnexpectedEOF(path);
}
}
}
public interface MyServiceLogger
{
public logUnexpectedEOF(Path path);
}
public class MyServiceTextLogger implements MyServiceLogger
{
private final Logger textLogger = LogManager.getLogger(MyService.class);;
@Override
public logUnexpectedEOF(Path path) {
textLogger.error("unexpected EOF for file {}",path);
}
}
你可以这样测试:
public class MyServiceTest
{
private static class MockMyServiceLogger implements MyServiceLogger
{
private Path path;
private int nCalls_logUnexpectedEOF;
@Override
public logUnexpectedEOF(Path path) {
++nCalls_logUnexpectedEOF;
this.path = path;
}
void assertCalled_logUnexpectedEOF(int nCalls, Path path) {
assertEquals("Called logUnexpectedEOF, nCalls", nCalls, nCalls_logUnexpectedEOF);
assertEquals("Called logUnexpectedEOF, path", path, this.path);
}
}
@Test
public void processFile_unexpectedEOF() {
Path testPath = ...
...
MockMyServiceLogger mockLogger = new MockMyServiceLogger();
MyService service = new MyService(mockLogger);
service.processFile(testPath);
mockLogger.assertCalled_logUnexpectedEOF(1, testPath);
}
@Test
public void processFile_OK() {
Path testPath = ...
...
MockMyServiceLogger mockLogger = new MockMyServiceLogger();
MyService service = new MyService(mockLogger);
service.processFile(testPath);
mockLogger.assertCalled_logUnexpectedEOF(0, null);
}
}