如何简化单元测试DDD值对象与AutoFixture相等

hoe*_*etz 6 c# unit-testing domain-driven-design autofixture

我目前正在使用xUnit,Moq和AutoFixture为我的Domain项目编写单元测试.我们来看看这个测试方法:

[Theory]
public void SameValueAs_OnOtherHasDifferentEmail_ReturnsFalse()
{
    Fixture fix = new Fixture();
    var sut = fix.CreateAnonymous<CoreAddress>();

    var other = new CoreAddress(
        sut.Firstname,
        sut.Lastname,
        sut.Company,
        sut.Street,
        sut.City,
        sut.ZIP,
        "other@email.com");

    Assert.False(sut.SameValueAs(other));
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我正在测试类CoreAddress及其SameValueAs方法.为了测试每个可能的情况,我必须创建测试方法OnOtherHasDifferentFirstname,OnOtherHasDifferentLastname等.这个模式可以吗?关于AutoFixture的使用,我能以某种方式简化这个吗?

Mar*_*ann 8

这种方法与我自己做的很相似.鉴于几乎所有的自动化测试都围绕着一些实际结果等于某些预期结果的测试,我从未真正理解为什么人们不希望自己单元测试平等.

对于像上面这样的值对象,它很容易变得有点乏味,因为它导致许多测试非常相似.

你可以使用xUnit.net的一个hack是这样的:

[Theory]
[InlineData("other first name", null, null, null, null, null, null)]
[InlineData(null, "other last name", null, null, null, null, null)]
[InlineData(null, null, "other company", null, null, null, null)]
[InlineData(null, null, null, "other street", null, null, null)]
[InlineData(null, null, null, null, "other city", null, null)]
[InlineData(null, null, null, null, null, "other zip", null)]
[InlineData(null, null, null, null, null, null, "other@email.com")]
public void EqualsIsFalseWhenAtLeastOneValueDiffers(
    string firstName,
    string lastName,
    string company,
    string street,
    string city,
    string zip,
    string email)
{
    Fixture fix = new Fixture();
    var sut = fix.CreateAnonymous<CoreAddress>();

    var other = new CoreAddress(
        firstName ?? sut.Firstname,
        lastName ?? sut.Lastname,
        company ?? sut.Company,
        street ?? sut.Street,
        city ?? sut.City,
        zip ?? sut.Zip,
        email ?? sut.Email);

    Assert.False(sut.Equals(other));
}
Run Code Online (Sandbox Code Playgroud)

然而,虽然它很紧凑,但我并不太热衷于做这样的事情,因为测试本身的圈复杂度为8 - 大约7太多......只是输入值的轻微错误配置可能会破坏测试并最终产生误报或漏报.

另一方面,我们都是程序员,如果事情变得重复,我们该怎么办?

写一些代码来消除乏味.这基本上就是AutoFixture.Idioms项目的全部内容,虽然它目前没有像上面这样的封装测试,但未来它可能会得到一个...它是开源的,我们偶尔会接受拉取请求;)