如何测试@Before方法?

时间:2016-05-22 07:34:23

标签: java junit

JUnit 4.12

我正在为类方法编写测试。这是它的样子

public interface MyInterface{
    //method declaration
}

public class MyClass implements MyInterface{

    private int a;
    private in b;

    public MyClass(int a, int b){
        if(a <= b + 5)
            throw new IllegalArgumentException("Invalid arguments");
        this.a = a;
        this.b = b;
    }

    //methods
}

现在我要测试这个类:

public class MyClassTest{
    private static final int THRESHOLD = 1000;

    private MyClass mc;

    @Before
    public void init(){
        Random rnd = new Random();
        int a = rnd.nexInt(THRESHOLD), 
            b = rnd.nexInt(THRESHOLD);
        mc = new MyClass(a, b);
    }
}

但在这种情况下,init()可能会抛出异常。所以我想测试保留不变量以及初始化一个对象以测试其他方法。

如何在JUnit中正确执行此操作?

3 个答案:

答案 0 :(得分:0)

@Before 旨在初始化测试所需的任何内容。如果你想检查任何东西 - @Test 方法是显而易见的。

在您的情况下,我认为您应该创建几个单独的测试方法,显式传递有效和无效的参数。这样,如果测试失败,您就知道它为什么会发生,如果它没有失败 - 您可以确定逻辑是正确的。 如果你使用随机你不能确定:也许测试的代码仍然是正确的或随机值是合适的,你很幸运。

答案 1 :(得分:0)

您需要两个测试类。

第一个用于测试构造函数行为。其次是测试方法的行为。 另外,我假设每个测试方法都需要@before。中定义的代码。

所以我们有:

public interface MyInterface{
    //method declaration
}

public class MyClass implements MyInterface{

private int a;
private in b;

public MyClass(int a, int b){
    if (a <= b + 5) {
        throw new IllegalArgumentException("Invalid arguments");
    }
    this.a = a;
    this.b = b;
}

//methods
}

现在我们为构造函数

创建测试
public class MyClassConstructorTest{
private static final int THRESHOLD = 1000;

@Test
public void allArgsConstructor_okValues_shouldCreateObjectOK(){
    // Given
    int a = 0; 
    int b = a - 5;
    // tested method
    new MyClass(a, b);
    // then no exception (test: ok)
}


@Test(expected = IllegalArgumentException.class)
public void allArgsConstructor_aLesserBplus5_shouldThrowException(){
    // Given
    int a = 0; 
    int b = a; 

    // tested method
    new MyClass(a, b);
    // then fail constructor assertion
    // see expected annotation
}

// other tests for constructor you need?

}

之后,您可以创建正常的测试:

public class MyClassTest{
private static final int THRESHOLD = 1000;

private MyClass mc;

@Before
public void init(){
    int a = 0; 
    int b = a+5;
    mc = new MyClass(a, b);
}

// normal test that use @before
}

PS:也在评论中指出:从不在测试中使用随机。

PS2:不确定你是否可以,但你可能应该将你的问题重命名为:&#34;如何测试构造函数方法&#34;

答案 2 :(得分:0)

我认为你的问题始于使用随机数。如果在单元测试中使用随机数,则必须确保所覆盖的范围适合一个案例而只有一个案例。在你的情况下,你实际上有三种情况:

  1. a&lt; b + 5 - 这会产生你的例外(顺便说一下,总是使用荣誉的好方法:{})。
  2. a&gt; b + 5 - 哪个是有效的案例。
  3. a = b + 5 - 这是另一个无效案例
  4. 您需要测试这三种情况,因此您需要针对每种情况进行设置。您遇到的问题是您尝试将所有案例合并为一个案例。在单元测试中非常不鼓励这种测试,因为您正在引入一个可变代码组件,正如您所说,需要对其进行测试。作为建议,使3 b变量b1和b2和b3

    说a是随机数。使b1 = a - 5 - 1,b2 = a - 5 + 1,b3 = a - 5.然后为每种情况提供3种测试方法。我建议您使用覆盖率工具,例如MoreUnit,因为它可以确保您检测到实际需要更轻松地测试的所有不同情况。