实例变量的Setter和getters的Junit测试

问题描述 投票:12回答:4

为对象内的实例变量的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);
}
java unit-testing junit
4个回答
20
投票

单元测试的主要原则是测试一个简单的代码单元;也就是说,每种方法都应该根据自己的优点进行测试。

这意味着我们不能在get测试中使用set方法,反之亦然 - 您不是在测试单个方法的单个代码单元。

鉴于...

假设我们有一个带有字段PlainOldJavaObjectvalue,我们想要(出于某种原因)测试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
投票

Use Bean Runner API

这将自动测试所有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

0
投票

我相信getter / setter测试确实有价值,因为它可以捕获拼写错误。但是由于代码生成工具的原因,这些错误并不常见,因此应该花费很少的时间。因此,使用工具执行这些测试而不是自己编写测试是很好的做法。

有一个图书馆可以提供帮助:OpenPojo

结合其他笔记......

  • 无需使用两种测试方法。使用一个,因为它将运行getter和setter。
  • 考虑使用Theory来测试一系列有效值(0, 1, Integer.MAX_VALUE)。您也可以使用TestedOn来传递这些int in-line example here
  • 测试错误条件,如通过-1

-1
投票

问题是你无法在任何一个测试中知道问题是在你的getter中还是在你的setter中,因为你必须用一个来测试另一个。你也可以

  • 用反射
  • 将您的私有字段标记为受保护并让您的测试继承自目标,
  • 或者不测试getter和setter

我仍然没有足够的经验来说出最好的是什么,但我知道它们都有缺点。

© www.soinside.com 2019 - 2024. All rights reserved.