测试返回类型为void的方法

时间:2014-09-19 19:00:15

标签: java testing junit mockito

我是软件测试的新手。在一个教程中,我读到我可以测试一些像这样的方法:

@Test
 public void testMultiply() {
   MyClass tester = new MyClass();
   assertEquals("10 x 5 must be 50", 50, tester.multiply(10, 5));
 } 

所以我必须将一些参数传递给方法并获得返回值 但在我的情况下,我有一些没有任何参数和返回值的类:

ArrayList al = new ArrayList();

public void Main(){
  methodA();
  methodB();
}

public void methodA(){
  // connect to URL
  // get some data
  for(int i=0; i<someThing; i++){
    al.add(data);
  }
}
public void methodB(){
  // do something with al
}

是否也可以测试它们?例如,正确的值是否来自methodA()中的网址。

5 个答案:

答案 0 :(得分:3)

可以测试不返回任何内容的方法(void),但必须测试该方法的副作用。它应该有一些副作用,否则这种方法是无用的。

此处的副作用是al已更改。如上所述,此类没有任何其他公开al的方法。添加一个getter方法,该方法返回ArrayListArrayList的特定元素。然后你的测试方法可以调用getter方法来检索值并将它(它们)与期望值进行比较。

答案 1 :(得分:2)

不带参数的方法用于返回值或其副作用。因此,这些方法的测试包括以下三个步骤:

  • 在调用无参数方法
  • 之前,将要测试的对象设置为初始状态
  • 调用无参数方法
  • 检查无参数方法的返回值或副作用

最后一步可以检查被测对象的新状态,或者它在系统整体环境中的工作结果。

这是一个小例子:

class Calculator {
    private int left, right, result;
    public void setLeft(int val) { left = val; }
    public void setRight(int val) { right = val; }
    public int getResult() { return result; }
    public void add() { result = left + right; }
    public void multiply() { result = left * right; }
}

您可以像这样测试其multiply()方法:

@Test
public void testMultiply() {
    // Set the object being tested to the initial state 
    Calculator tester = new Calculator();
    tester.setLeft(5);
    tester.setRight(10);
    // Call the method
    tester.multiply();
    // Check the new state
    assertEquals("10 x 5 must be 50", 50, tester.getResult());
}

此示例测试该方法的副作用。测试具有返回值且没有副作用的方法会将方法的调用与对断言行的检查结合起来。

答案 2 :(得分:2)

是的,当然你可以测试没有参数的方法。

可能是一个例子是看到这个的最佳方式。想想ArrayList.clear()方法。它的作用是清空ArrayList,使其大小为零。您可以通过以下方式测试此方法:

  1. 创建ArrayList arr;
  2. 添加一些东西;
  3. 调用arr.clear();
  4. 检查assertEquals(arr.size(),0)
  5. 换句话说,您需要进行设置,以便ArrayList拥有您不想要的州(size()>0);然后你调用应该对状态产生可预测影响的方法(将size()设置为0);然后检查效果是否符合预期。

答案 3 :(得分:1)

是的,如果您在其他方法中使用这些方法作为副作用,则可以测试这些方法。 例如 -

public class test{
public int i=0;
public void incrementIngeterValue()
{
  //doing something and 
   i++;
}

public boolean incremented()
{
  //some logic to check what is current i value
  int x = incrementIngeterValue();

  if(x==i)
       return false; // value not incremented
  else
       return true // in this case you can make sure this value is incremented by 1.


}

所以你可以测试递增的方法来检查i值是否增加1,用这个方法你可以在内部测试你的incrementIngeterValue()而没有参数和返回值。

在你的情况下,a1在两种方法中都有效。你正在使用这个a1。

答案 4 :(得分:0)

在这种情况下,您尝试测试呼叫的副作用,而不是呼叫本身的输出(例如返回值)。您可以通过多种不同方式对此进行测试:

  1. 如果副作用可见,请测试其结果是否符合您的期望
  2. 如果由于调用外部接口而不容易看到副作用,请使用mocking frameworkPowerMock将外部接口替换为模拟对象,以便您可以观察和测试调用外部接口
  3. 重新设计您的界面以使其更易于测试。 :)
  4. 在您的特定情况下,我会为al添加一个访问器,并在调用AMethod()后检查其内容是否匹配。

    一般来说,对于单元测试,您不想连接到外部URL,数据库等,因为它速度慢而且价格昂贵。您希望将这些调用替换为可以模拟它们的数据提供者。