2014-09-19 204 views
1

我是软件测试的新手。在教程中,我读,我可以测试一些像这样的方法:测试返回类型的方法void

@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()中的URL。

+0

当然可以。它看起来像'methodA()'正在修改'ArrayList'的内部状态,所以你可以让你的测试类在执行该方法之前和之后检查列表的内容。 – azurefrog 2014-09-19 19:03:56

+0

是的,它取决于什么是重要的,你可以使用mockito来验证实现是否被调用,或者你可以验证它发生变异的对象。 – StackFlowed 2014-09-19 19:04:05

+0

当然。通常,如果在没有参数和返回值的情况下调用函数期间没有发生错误,则表示该函数可以工作。当然,这根本不是真的。为此,您可以简单地使用调试器并测试程序的流程。 – nbro 2014-09-19 19:04:06

回答

4

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

这里的副作用是al已更改。正如所写的,这个类没有任何其他暴露al的方法。添加一个getter方法,该方法返回ArrayListArrayList的特定元素。然后,您的测试方法可以调用getter方法来检索值并将其与预期值进行比较。

+1

我应该仅添加此方法,以便测试类可以调用它?即使我实际上并不需要它在我的代码中? – user1170330 2014-09-19 20:14:43

+0

这些数据是如何使用的?如果其他方法(如methodB)使用它,则可以使用'methodB'并测试其副作用。 – rgettman 2014-09-19 20:22:06

+0

@ user1170330是的。你正在编写一个可测试的组件,这意味着要编写足够的访问器来测试它。如果这些不应该在生产中被调用,请将它们记录下来。 – 2014-09-19 20:37:34

1

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

  • 设置对象正被试验的初始状态调用参数方法
  • 调用参数方法
  • 检查返回值或副作用之前的无参数方法

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

这里是一个小例子:

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()); 
} 

方法的这种抽样检验的副作用。测试的方法有返回值,无副作用将结合其在断言线检查方法的调用。

+0

值得澄清:无参数*或返回值*的方法用于其副作用。没有参数但带有返回值的方法不需要有副作用(例如getter方法)。 – 2014-09-19 19:14:23

+0

@ chiastic-security这是一个公正的观察,非常感谢! – dasblinkenlight 2014-09-19 19:17:35

0

在这种情况下,你想测试呼叫,而不是输出(例如,返回值)的调用本身的副作用。

  1. 如果副作用是可见的,测试他们的结果符合您的预期
  2. 如果副作用是不容易看到,因为它们调入外部接口:您可以在许多不同的方式测试这个,使用mocking frameworkPowerMock与模拟对象来代替外部接口,这样就可以对来电观察和测试,外部接口
  3. 重新设计你的界面更加可测试。:)

在你的具体情况下,我会添加一个访问器,并检查其调用AMethod()后的预期内容。

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

1

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

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

  1. 创建ArrayList arr;
  2. 添加一些东西给它;
  3. 调用arr.clear();
  4. 检查assertEquals(arr.size(),0)

换句话说,你设置的东西了,这样你的ArrayList有一个状态,你不希望(size()>0);那么你正在调用应该对状态产生可预测影响的方法(设置size()0);然后检查效果是否符合您的预期。

+0

如果在我的实现中实际上不需要方法size()会怎么样?我应该创建它以便测试课程可以使用它吗? – user1170330 2014-09-19 19:19:08

+0

嗯,重点在于被测试的方法必须对状态有一定的影响,并且状态的改变必须能够用已经存在的方法检测到,否则该方法是毫无意义的,或者您需要一些更多的方法!换句话说,如果你没有任何依据你是否清除了'ArrayList'而采取不同行为的方法,那么清除它就永远没有任何意义。 – 2014-09-19 19:25:13

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. 


} 

所以,你可以检查我的值增加1或不用,用这种方法,你在内部没有参数和返回值测试incrementIngeterValue()测试递增方法。

在你的情况下,你的a1受到两种方法的影响。某处你正在使用这个a1。

相关问题