我对单元测试相当新,并且已经在网上阅读了大量资料,但我在解决问题方面遇到了一些麻烦。
例如:如果我有以下代码:
public class RandomClass
{
int a = 4;
public void foo(Object obj)
{
if(a == 4)
{
AnotherObject anotherObj = new AnotherObject();
anotherObj.setAttribute(obj.getFiled());
//Method call that will be suppressed
Anotherclass.anotherMethod(anotherObj);
}
}
}
我想过写这样的junit测试用例:
@Test
public void testFoo()
{
int a=4;
RandomClass randomClass = new RandomClass();
Object object = new Object();
object.setField("hey");
randomClass.foo(object);
}
我在这里有几个问题。 我怎样从junit设置整数a?我现在设置它的方式并不会影响单元测试用例。当我调试单元测试时,a的值为NULL,因此它永远不会通过if条件!
此外,方法foo返回一个void,那么我可以测试/断言什么?
答案 0 :(得分:1)
编写单元测试时有两种主要技巧:
您知道,您实际上编写了“难以测试”的代码 - 因为您在生产代码中为 AnotherClass 调用了 new 。这似乎不是什么大问题,但取决于 AnotherClass 的内容......你真的不应该这样做!
无论如何;我建议您查看这些videos以了解如何编写更适合单元测试的代码。
答案 1 :(得分:1)
测试通常以“设置”,“准备”或“排列”步骤开始,在此步骤中,它会创建或修改被测对象,使其处于特定测试所需的状态。
因此,如果a
对象中的字段RandomClass
需要具有值4
(例如),则测试需要创建将此值作为构造函数传递的对象参数,或通过调用setter方法或直接访问该字段来设置对象中的值。在最坏的情况下,您可能需要使用Reflection来设置字段,但这表明正在测试的类中存在设计问题。
下一步是练习测试中的代码。这是“安排,行动,断言”术语中的“行为”步骤(简称AAA)。
最后,最后一步是“断言”(验证)正在测试的代码做了应该做的事情。
如果正在测试的方法具有void
返回类型,那么测试应该通过状态验证或行为验证来验证它是否达到预期效果。
在第一种情况下,测试会在被测对象中调用一些getter方法,并在某种“断言”中使用它(例如,assertEquals(expectedValue, actualValue)
)。
在第二种情况下,测试将使用一些模拟库,以验证期望的调用是从测试中的代码到一个或多个依赖项(其他对象或类所在的类)在测试中取决于)。例如,此处测试可以验证RandomClass#foo
确实调用Anotherclass.anotherMethod(...)
。