如何避免重复的JUnit测试

时间:2014-01-07 10:56:24

标签: java junit dry

我正在为某些userdata实现验证器。

不幸的是,userdata包含总共37个字段,这使得测试类非常可怕。

大多数字段包含具有类似要求的数据(即检查长度限制)。

代码摘录:

public class Userdata {

    private String            firstName;
    private String            lastName;
    private String            birthName;
    private String            birthPlace;
    private String            city;
    private String            street;
    private String            zipCode;
    private String            country;
    private String            citizenship;

    // getters/setters
}

和(部分)测试类:

public class UserdataValidatorTest {
    UserdataValidator cut = new UserdataValidator();

    @Test
    public void firstNameMaxPermittedLength()
    {
        Userdata userdata = minimumRequirements();
        userdata.setFirstName( utf8Chars( 64 ) );

        assertNoViolations( cut.validate( userdata ) );
    }

    @Test
    public void firstNameExceedsPermittedLength()
    {
        Userdata userdata = minimumRequirements();
        userdata.setFirstName( utf8Chars( 65 ) );

        assertSingleViolation( cut.validate( userdata ) );
    }

    @Test
    public void lastNameMaxPermittedLength()
    {
        Userdata userdata = minimumRequirements();
        userdata.setLastName( utf8Chars( 64 ) );

        assertNoViolations( cut.validate( userdata ) );
    }

    @Test
    public void lastNameExceedsPermittedLength()
    {
        Userdata userdata = minimumRequirements();
        userdata.setLastName( utf8Chars( 65 ) );

        assertSingleViolation( cut.validate( userdata ) );
    }

    @Test
    public void citizenshipIllegalChars()
    {
        Userdata userdata = minimumRequirements();
        userdata.setCitizenship( "2E" );

        assertSingleViolation( cut.validate( userdata ) );
    }

    @Test
    public void citizenshipLegal()
    {
        Userdata userdata = minimumRequirements();
        userdata.setCitizenship( iso3166Country() );

        assertNoViolations( cut.validate( userdata ) );
    }

    @Test
    public void citizenshipTooLong()
    {
        Userdata userdata = minimumRequirements();
        userdata.setCitizenship( alphabetic( 3 ) );

        assertSingleViolation( cut.validate( userdata ) );
    }

    @Test
    public void citizenshipTooShort()
    {
        Userdata userdata = minimumRequirements();
        userdata.setCitizenship( alphabetic( 1 ) );

        assertSingleViolation( cut.validate( userdata ) );
    }

    @Test
    public void countryIllegalChars()
    {
        Userdata userdata = minimumRequirements();
        userdata.setCountry( "2E" );

        assertSingleViolation( cut.validate( userdata ) );
    }

    @Test
    public void countryLegal()
    {
        Userdata userdata = minimumRequirements();
        userdata.setCountry( iso3166Country() );

        assertNoViolations( cut.validate( userdata ) );
    }

    @Test
    public void countryTooLong()
    {
        Userdata userdata = minimumRequirements();
        userdata.setCountry( alphabetic( 3 ) );

        assertSingleViolation( cut.validate( userdata ) );
    }

    @Test
    public void countryTooShort()
    {
        Userdata userdata = minimumRequirements();
        userdata.setCountry( alphabetic( 1 ) );

        assertSingleViolation( cut.validate( userdata ) );
    }

    // ... more tests
}

是否有一种令人愉快的方式来生成测试用例?我仍然想为每个国家进行4次测试。

修改

有许多复杂的(相互依赖)字段,我在这里省略了,这就是我决定不使用Bean Validation API的原因。

2 个答案:

答案 0 :(得分:2)

恕我办公室单元测试不是生产代码,不必保持相同的标准。您可以轻松地重构和删除测试代码,而不会直接影响生产。对我来说,DRY对生产代码有意义,但WET(Write Everything Twice)也适用于单元测试代码。

要直接回答你的问题,你可以使用一个循环,你可以结合测试,但我怀疑它们没有多大帮助。

e.g。

@Test
public void firstNameMaxPermittedLength() {
    Userdata userdata = minimumRequirements();
    userdata.setFirstName(utf8Chars(64));
    assertNoViolations(cut.validate(userdata));

    userdata.setFirstName(utf8Chars(65));
    assertSingleViolation(cut.validate(userdata));
}

答案 1 :(得分:0)

如果所有这些字段都做同样的事情并且名称是一致的,为什么不只是向类请求其方法列表,循环遍历所有以set开头的字段,并做任何事情你都做需要做什么?