我正在为try-catch块编写测试,但我对如何测试catch块感到困惑。。。特别是它使用slf4j来记录错误。
addText这里是来自同一类的另一个方法。
public class TextQueue {
public void addTextToQueue(final Text text) {
try {
if (text != null) {
addText(text);
}
} catch (final JsonProcessingException e) {
LOGGER.error("Error adding text to the queue : {}", e);
}
}
}
这是我的测试用例
@RunWith(MockitoJUnitRunner.class)
public class TextQueueTest {
private org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TextQueueTest.class);
private static final String MY_TEXT = "src/text.json";
private Text text;
private final ObjectMapper mapper = new JacksonConfig().dateAsStringObjectMapper();
@Mock
private TextQueue textQueue;
@Before
public void setUp() throws IOException {
text = mapper.readValue(new File(TextQueueTest.MY_TEXT), Text.class);
}
@Test
public void addTextToQueue() {
try{
textQueue = spy(textQueue);
textQueue.addTextToQueue(text);
}catch(final Exception e){
LOOGER.error("add text to queue threw an error" + e);
}
}
有人能帮我解决这个问题吗?
首先,你应该读一本关于Mockito的好教程,比如vogella的教程。你看,你只是把很多没有意义的东西拼凑在一起。
类似:
@Mock
private TextQueue textQueue;
然后进行
textQueue = spy(textQueue);
在您的测试用例中。你应该非常清楚这一点。间谍是在测试中的类的真实实例上构建的。正如所说,制造一个监视模拟的间谍是没有意义的。
然后:
}catch(final Exception e){
Logger.error("add text to queue threw an error" + e);
再说一遍,毫无意义。单元测试的全部思想是,当出现问题时,它们会失败。当您的生产代码抛出意外异常时,您不记录它们,只是让它们最终使您的测试用例失败。
要回答实际问题:看起来就像您的生产代码正在使用特定的"常量"记录器实例。考虑到这种设计,检查生产代码的唯一方法是:
- 使LOGGER成为一个模拟对象
- 以某种方式将它注入到生产代码类的实例
underTest
中 - 触发该方法在
underTest
上进行测试(并以某种方式强制该方法抛出异常) - 验证模拟LOGGER是否看到了对
error()
的预期调用
我们无法提供更好的建议,因为您的代码输入不足,我们不知道您的生产类在做什么(例如:我们不知道LOGGER是什么,它来自哪里。如果它恰好是一个静态变量,那么很可能,您无法用Mockito"控制"它)。
无论如何,您可能实际上需要间谍概念。为了测试addTextToQueue()
,您需要一种方法来调用"真正的"addTextToQueue()
实现,但其中对addTser()
的调用需要转到mock(这样您就可以控制该调用的作用)。
但正如所说:从真正研究Mockito的工作原理开始,而不是用一些"试错"的方法把毫无意义的东西拼凑在一起。正确的单元测试和嘲讽是复杂的,你不能通过"试错"来学习。