为对象中的实例变量的setter和getter创建测试用例。什么是最好的方法?在这里,我在我的测试中使用get和set方法。这会是一个糟糕的测试策略吗?
/**
* Test of setFlightNumber method, of class Flight.
*/
@Test
public void testSetFlightNumber() {
System.out.println("setFlightNumber");
int flightNumber = 1000;
Flight instance = new Flight();
instance.setFlightNumber(flightNumber);
// TODO review the generated test code and remove the default call to fail.
assertEquals(instance.getFlightNumber(), flightNumber);
}
/**
* Test of getFlightNumber method, of class Flight.
*/
@Test
public void testGetFlightNumber() {
System.out.println("getFlightNumber");
Flight instance = new Flight();
int expResult = 1000;
instance.setFlightNumber(1000);
int result = instance.getFlightNumber();
assertEquals(expResult, result);
}
答案 0 :(得分:21)
单元测试的主要原则是测试一个简单的单元代码;也就是说,每种方法都应该根据自己的优点进行测试。
这意味着我们无法在get
测试中使用set
方法,反之亦然 - 您不会测试单个方法的单个代码单元。
鉴于......
假设我们有PlainOldJavaObject
字段value
我们想要(出于某种原因)测试setter和getter的有效性。唯一合适的方法是通过use of reflection。
这是我的类声明,非常瘦:
public class PlainOldJavaObject {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
我现在设置我的测试类来利用反射;特别是使用Field
类:
public class PlainOldJavaObjectTest {
@Test
public void testSetter_setsProperly() throws NoSuchFieldException, IllegalAccessException {
//given
final PlainOldJavaObject pojo = new PlainOldJavaObject();
//when
pojo.setValue("foo");
//then
final Field field = pojo.getClass().getDeclaredField("value");
field.setAccessible(true);
assertEquals("Fields didn't match", field.get(pojo), "foo");
}
@Test
public void testGetter_getsValue() throws NoSuchFieldException, IllegalAccessException {
//given
final PlainOldJavaObject pojo = new PlainOldJavaObject();
final Field field = pojo.getClass().getDeclaredField("value");
field.setAccessible(true);
field.set(pojo, "magic_values");
//when
final String result = pojo.getValue();
//then
assertEquals("field wasn't retrieved properly", result, "magic_values");
}
}
在第一个测试中,我确保通过反复访问PlainOldJavaObject
实例的字段中包含的值来读取字段。在不违反声明的类*的完整性的情况下,我确信该领域正在适当地设置。
在第二个测试中,我假设该值已经设置为先前的值,因此设置涉及使用已知的默认值填充该字段。当我读回值时,我断言读回的值是我们知道最初设置的值。
最终,如果你有很多制定者和吸气者,你将不得不做这样的代码(因为,如果你依赖于你的制定者和吸气剂“只是工作”的假设,就像你在上面的测试中一样,您的测试用例可能无效)。
*:请注意,反射是一种快速而快速的方法,可以通过未定义的行为进入极端麻烦,并且几乎没有对象不变性的保证。你正在采取语言的收缩包装,并做着奇怪和不寻常的事情。继续自担风险。
答案 1 :(得分:1)
这将自动测试所有的getter和setter,确保正确设置值。
testBean
public void testBean(java.lang.Object bean)
throws java.lang.Exception
Test the properties that have both getters and setters. Exclude those who have been excluded by excludeProperty(String). If the object implements Serializable, do a check to ensure it really is.
Parameters:
bean - the object to test
Throws:
java.lang.Exception - on failure
答案 2 :(得分:1)
我认为用于测试吸气剂和吸气剂的方法是完全有效的,恕我直言,我认为这就是应该测试吸气剂-设置器的方式。
我听到的一个常见的说法是,单元测试应该只测试一个单元,因此只能测试一个类的单个方法。但是,在那种情况下,我们最好将其称为单方法测试。一个单元,如果可能的话,应该是一种方法,但不仅仅是一个用例!
考虑这样的课程
public class PlainObject {
void setA(int a) {
}
}
在这种情况下,如果编写任何调用该方法的单元测试,它将通过,因为此方法不执行任何操作。这是完全正确的,因为调用此方法是唯一可能的用例。它不会以任何方式影响应用程序的行为。
进行一个同时使用getter和setter的测试是正确的,因为您本身无法测试setter方法的行为。而且,在执行获取之前,setter的行为甚至都无关紧要。如果我做的只是叫一个setter,却从不获取该值或以任何其他方式使用它,那就没有setter了。
使用反射或其他奇特的方式仅测试实现。这些方法不会测试代码的行为。最后,您最终将代码编写为无用的测试。
我唯一要做的更改是将测试方法的名称从testSetter更改为testAccess,因为您正在读取和更新值。
答案 3 :(得分:0)
我相信getter / setter测试确实有价值,因为它可以捕获拼写错误。但是由于代码生成工具的原因,这些错误并不常见,因此应该花费很少的时间。因此,使用工具来执行这些测试而不是自己编写测试是很好的做法。
有一个图书馆可以提供帮助:OpenPojo
结合其他笔记......
Theory
来测试一系列有效值(0, 1, Integer.MAX_VALUE
)。您也可以使用TestedOn来传递这些内联example here -1
答案 4 :(得分:-1)
问题在于,您无法在任何一个测试中知道问题是在您的getter中还是在您的setter中,因为您必须使用一个来测试另一个。你可以
使用反射
将您的私有字段标记为受保护并让您的测试继承目标,
或不测试getter and setters
我还没有足够的经验告诉他们最好的是什么, 但我知道它们都有缺点。