Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带有slif4j日志的try catch块的mockito测试出现问题_Java_Unit Testing_Spring Boot_Testing_Mockito - Fatal编程技术网

Java 带有slif4j日志的try catch块的mockito测试出现问题

Java 带有slif4j日志的try catch块的mockito测试出现问题,java,unit-testing,spring-boot,testing,mockito,Java,Unit Testing,Spring Boot,Testing,Mockito,我正在为一个try-catch块编写测试,但我对如何测试catch块感到非常困惑…尤其是它使用slf4j来记录错误 addText是来自同一类的另一个方法 public class TextQueue { public void addTextToQueue(final Text text) { try { if (text != null) { addText(text);

我正在为一个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的很好的教程,比如来自美国的那本。你看,你只是简单地把很多非感官的东西放在一起

比如:

@Mock
private TextQueue textQueue;
拥有

textQueue = spy(textQueue);
在您的测试用例中。你应该非常清楚这一点。间谍是在测试类的真实实例上构建的。创造一个间谍,在一个模拟间谍,如说:这是没有意义的

然后:

}catch(final Exception e){
    Logger.error("add text to queue threw an error" + e);
再一次,非感官的。单元测试的整体思想是,当出现问题时,单元测试会失败。当您的生产代码抛出意外的异常时,您不会记录它们,最终只会让它们在测试用例中失败

回答实际问题:生产代码似乎正在使用特定的“常量”记录器实例。鉴于这种设计,检查生产代码的唯一方法是:

  • 使该记录器成为模拟对象
  • 以某种方式将其注入到生产代码类的一个实例
    测试中
  • 触发该方法在
    测试下进行测试(并以某种方式强制该方法引发异常)
  • 验证模拟记录器是否看到了对
    error()的预期调用
我们无法给出更好的建议,因为您的代码输入不足,我们不知道您的生产类在做什么(例如:我们不知道什么是LOGGER,它来自哪里。如果它恰好是一个静态变量,那么很可能您无法用Mockito对其进行“控制”)

在任何情况下,您可能实际上需要间谍概念。为了测试
addTextToQueue()
您需要一种方法来调用“real”
addTextToQueue()
实现,但是对内
addTser()
的调用需要转到模拟(以便您可以控制该调用的功能)


但如前所述:从真正研究Mockito的工作原理开始,而不是将一些“尝试和错误”方法中毫无意义的东西放在一起。使用模拟进行正确的单元测试是复杂的,您无法通过“试错法”了解这一点。

请注意:您的更新增加了混乱。现在您的测试类将不再编译,并且提示:在测试类中声明记录器实例对您的生产代码没有任何影响。从这个角度来看,如果可能的话,你可能应该重新审视并加强你的问题。或者让我知道我的答案中缺少了什么/如果。所以我不应该在测试中包括LOGGER,要用原始方法测试catch块,最好的方法是触发异常,然后验证异常,对吗@这取决于你想做什么。如果您只需检查:addTextToQueue()就可以捕获任何异常,那么不抛出异常的测试就足够了。但是,如果您想确保将某些消息写入记录器,则需要对其进行控制。再次强调:在测试用例中有一个LOGGER实例对您的产品代码没有任何作用。感谢您的建议,如果异常通过,我将尝试找到检查日志的方法。我感谢您的快速恢复!如前所述:关键是获得对记录器对象的控制。您可能想了解依赖项注入。真正的问题是:记录器实例如何进入您的生产代码?当你明白了这一点,你可以看看你的选择。这可能是你可以推一个模拟的记录器,如果这是不可能的,是的,看看真实记录器的“输出”就可以了。(但我建议避免这种情况,您希望将单元测试与任何“真实”的东西(如文件系统中的文件)隔离开来)