2016-05-22 74 views
0

JUnit 4.12如何测试@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 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中正确执行此操作?

+4

该单元测试的设计不正确。你通常会有3个测试用例,它们的固定值是'a'和'b'。我们测试一下'a'低于'b + 5'的情况,一个测试'a'等于'b + 5'的情况,最后一个测试'a'大于'b + 5'的情况。使用'随机'在这里没有必要或有帮助。 – Tom

+0

为什么在@之前呢?如果你想测试异常,只是一个测试。 – RobAu

+1

在大多数情况下,测试时使用随机/非确定性值是一个坏主意。即使在应该以某种随机方式行事的课堂中,测试也通常被设计为使得他们的行为以某种方式变得可预测。 –

回答

0

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

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

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:“如何测试构造方法”

0

我觉得你的问题,使用随机数的开始:如果你可以,但你应该你的问题重命名为不确定。如果您在单元测试中使用随机数字,您必须确保您所覆盖的范围适合一种情况并且只有一种情况。你的情况,你实际上有三种情况:

  1. 一个< B + 5 - 产生的异常(顺便说一句,这是很好的做法,始终使用赞誉:{})。
  2. a> b + 5 - 这是有效的情况。
  3. A = B + 5 - 这是另一种无效的情况下

您需要测试的三种情况,所以你需要为每个案件的设置。您正在运行的问题是,您正试图将所有案例合并为一个。这种测试在单元测试中非常令人沮丧,因为您正在引入一个可变代码组件,并且您所说的需要进行测试。作为一个建议,做3个变量b1和b2和b3

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