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

时间:2014-01-25 18:12:57

标签: java unit-testing junit

为对象中的实例变量的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);
}

5 个答案:

答案 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)

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

答案 2 :(得分:1)

我认为用于测试吸气剂和吸气剂的方法是完全有效的,恕我直言,我认为这就是应该测试吸气剂-设置器的方式。

我听到的一个常见的说法是,单元测试应该只测试一个单元,因此只能测试一个类的单个方法。但是,在那种情况下,我们最好将其称为单方法测试。一个单元,如果可能的话,应该是一种方法,但不仅仅是一个用例!

考虑这样的课程

public class PlainObject {

    void setA(int a) {
    }
 }

在这种情况下,如果编写任何调用该方法的单元测试,它将通过,因为此方法不执行任何操作。这是完全正确的,因为调用此方法是唯一可能的用例。它不会以任何方式影响应用程序的行为。

进行一个同时使用getter和setter的测试是正确的,因为您本身无法测试setter方法的行为。而且,在执行获取之前,setter的行为甚至都无关紧要。如果我做的只是叫一个setter,却从不获取该值或以任何其他方式使用它,那就没有setter了。

使用反射或其他奇特的方式仅测试实现。这些方法不会测试代码的行为。最后,您最终将代码编写为无用的测试。

我唯一要做的更改是将测试方法的名称从testSetter更改为testAccess,因为您正在读取和更新值。

答案 3 :(得分:0)

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

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

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

  • 无需使用两种测试方法。使用一个,因为它会使得getter和setter都无法使用。
  • 考虑使用Theory来测试一系列有效值(0, 1, Integer.MAX_VALUE)。您也可以使用TestedOn来传递这些内联example here
  • 测试错误条件,例如传递-1

答案 4 :(得分:-1)

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

  • 使用反射

  • 将您的私有字段标记为受保护并让您的测试继承目标,

  • 或不测试getter and setters

我还没有足够的经验告诉他们最好的是什么, 但我知道它们都有缺点。