我怎么能单元测试无效的功能呢?我怎么能单元测试无效的功能呢?(How can I unit test

2019-05-12 11:56发布

class Elephant extends Animal {   
    public Elephant(String name) {
        super(name);
    }

    void makeNoise() {
        logger.info(" Elephant  make Sound");
    }

    void perform(String day) {
        if (day.equals("thursday") || day.equals("friday")) {
            makeNoise();
        }
    }
}

现在我想测试的perform方法。 我怎么能单元测试这种方法使用JUnit?

Answer 1:

与间谍的Mockito解决方案

import org.junit.Test;

import static org.mockito.Mockito.*;

public class ElephantTest {

    @Test
    public void shouldMakeNoise() throws Exception {

        //given
        Elephant elephant = spy(new Elephant("foo"));

        //when
        elephant.perform("friday");

        //then
        verify(elephant).makeNoise();

    }
}

负面测试:

@Test
public void elephantShouldDontMakeNoisesOnMonday() {

    //given
    Elephant elephant = spy(new Elephant("foo"));

    //when
    elephant.perform("monday");

    //then
    verify(elephant, never()).makeNoise();

}

要么

@Test
public void shouldDoNotMakeNoisesOnMonday() {

    //given
    Elephant elephant = spy(new Elephant("foo"));

    //when
    elephant.perform("monday");

    then(elephant).should(never()).makeNoise();

}

依赖

org.mockito:mockito-core:2.21.0

阅读

  • #的Mockito doNothing()
  • #的Mockito间谍(T)


Answer 2:

void()函数改变程序的状态。 这可以通过修改变量,文件,数据库等进行

在你的情况你写日志中记录。 如果这导致写作“大象使声音”文件,然后你可以阅读该文件,并查看该文件中的数据包括你吵的大象。

如果然而,不涉及任何你可以检查(即:它只是在控制台上显示输出),那么你可能想看看一些形式的依赖注入(DI),您可以设置输出到文件或别的东西您可以轻松地阅读。

应当注意的是,你可以嘲笑对象,选中相应的方法获取调用绕过DI。



Answer 3:

为了测试的任何方法,将待测试的责任必须通过改变任何变量的状态是可见的,从该方法的输出侧。

通常,它是通过从该方法返回值来完成。 但是,如果没有的是,它可以在许多方面通过修改从法范围之外的东西做,如果你有任何“问题”,从方法返回的东西!

在你的情况,你只能记录一些信息。 和你的代码是不是在某种意义上说,它不会做的东西,直接关系到改变任何变量的状态(因为你改变不是变量以外的其他资源的状态真的可测试的,这是不是你的代码直接访问。您必须写一些代码来读取来自外部资源的变化,从而使你的测试代码依赖于读也。如果你有一些问题,阅读,你的测试用例不会通过,并且不与单位的精神去测试。其主要思想是,以减少对外部代码或库尽可能)的依赖性。 但是,你的代码可以做轻微的重构/移责任心像下面可测试:

String makeNoise() {
    return "Elephant  make Sound";
}

String perform(String day) {
    if (day.equals("thursday") || day.equals("friday")) {
      return makeNoise();
    }
}

然后你登录移动从返回的值有责任perform方法来使用它像下面这样:

 logger.info(perform(day));


Answer 4:

你必须根据你愿意使用的工具,你的测试应该具有深度的各种选项。

部分嘲讽与普通的Java

创建一个从大象扩展一个类(MockElephant),覆盖makeNoise所以它计算调用次数。 使用这个类在您的测试,以检查makeNoise被称为正确的次数

与框架部分嘲讽你基本同上,但代替手工编码MockElephant你使用一些模拟框架创建它。 使得测试更加简单,因为你需要更少的代码。 它是更容易阅读。 但是,如果奇异的事情发生就更难明白是怎么回事。 在嘲弄框架的情况下,我认为他们是值得的。

为什么这个被称为偏嘲讽的原因是,你嘲笑只有课程的部分(在这种情况下,单一的方法)。

另一种方法是使用普通嘲笑 ,而你的情况似乎是可行的(但可以成为遗留代码韧)。

在这里,你会注入记录仪作为一个依赖。 例如,你可以创建一个额外的构造函数,它允许您提供记录仪。 在您的测试,你会然后用嘲笑Logger,也开始重新计数它的调用,可能与它收到的参数一起,并检查它的预期值。

同样,你可以做到这一点嘲弄的框架或普通的Java。



文章来源: How can I unit test void functions?