سؤال

I'm currently writing Unit Tests for my Domain project with xUnit, Moq and AutoFixture. Let's have a look at this Test Method:

[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));
}

As you can see I'm testing the class CoreAddress and its SameValueAs Method. To test every possible case, I'd have to create the Test methods OnOtherHasDifferentFirstname , OnOtherHasDifferentLastname etc. Is this pattern okay? Can I somehow simplify this with regards to AutoFixture usage?

هل كانت مفيدة؟

المحلول

That approach is quite similar to what I would do myself. Given that almost all automated testing revolves around testing that some actual result is equal to some expected outcome, I never really understood why people wouldn't want to unit test equality itself.

With a value object like the above, it can easily become a bit tedious, as it leads to many tests which are all very similar.

One hack you could use with xUnit.net is this:

[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));
}

However, while it's compact, I'm not too keen on doing something like this, as the test itself has a cyclomatic complexity of 8 - which is about 7 too much... Only a slight misconfiguration of the input values could ruin the test and in the end produce either false positives or false negatives.

On the other hand, we're all programmers here, and if things become repetitive, what should we do?

Write some code to take away the tedium. This is basically what the AutoFixture.Idioms project is all about, and while it doesn't currently have an encapsulated test like the one above, it might get one in the future... it's open source, and we do occasionally take pull requests ;)

نصائح أخرى

I wouldn't bother unit testing value objects equality as far as I'm concerned. If you really want to do it, there are ways of abstracting this kind of unit tests and make them much less tedious to write : http://kennethxu.blogspot.fr/2009/11/unit-test-value-object.html

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top