Question

Does this test make proper use of AutoFixture and Moq? Is it written as concisely as possible? The test fails, as expected, and passes after writing the correct implementation.

[Fact]
public void CustomerPropertyIsCorrect()
{
    var fixture = new AutoMoqFixture();

    var expected = fixture.Create<CardHolderCustomer>();
    var builderMock = fixture
        .Freeze<Mock<ICustomerAdapter>>()
        .Setup(x => x.BuildCustomer()).Returns(expected);

    var sut = fixture.Create<CardHolderViewModel>();
    var actual = sut.Customer;

    Assert.Equal(expected, actual);
}
Was it helpful?

Solution

It's looking good! However, you can also use it declaratively with the xUnit.net extension.

Assuming that the types used in the test are defined as:

public class CardHolderCustomer
{
}

public interface ICustomerAdapter
{
    CardHolderCustomer BuildCustomer();
}

public class CardHolderViewModel
{
    private readonly ICustomerAdapter adapter;

    public CardHolderViewModel(ICustomerAdapter adapter)
    {
        if (adapter == null)
            throw new ArgumentNullException("adapter");
        this.adapter = adapter;
    }

    public CardHolderCustomer Customer
    {
        get
        {
            return this.adapter.BuildCustomer();
        }
    }
}

The original test can be written as:

[Theory, DomainTestConventions]
public void CustomerPropertyIsCorrect2(
    CardHolderCustomer expected,
    [Frozen]Mock<ICustomerAdapter> builderStub,
    CardHolderViewModel sut)
{
    builderStub
        .Setup(x => x.BuildCustomer())
        .Returns(expected);

    var actual = sut.Customer;

    Assert.Equal(expected, actual);
}

The DomainTestConventionsAttribute is defined as:

internal class DomainTestConventionsAttribute : AutoDataAttribute
{
    internal DomainTestConventionsAttribute()
        :base(new Fixture().Customize(new DomainTestConventions()))
    {
    }
}

The DomainTestConventions is defined as:

internal class DomainTestConventions : CompositeCustomization
{
    internal DomainTestConventions()
        :base(new AutoMoqCustomization())
    {
    }
}

Note that DomainTestConventions derives from CompositeCustomization which basically means that you can create more Customizations and add them as parameters to the base constructor.

You may also read:

Hope that helps.

OTHER TIPS

I think this is concise and readable. But I question the value of this kind of test.

Your test is named CustomerPropertyIsCorrect, so I assume this is what you want to test. Since you instruct the BuildCustomer method of your ICustomerAdapter to return the frozen instance created earlier, and since the view model code will use this code when run in xUnit, yes, the frozen object will indeed be returned.

Now, I'm not all-in the TDD camp (yet) so this may just be me, not "getting" TDD. But as far as I can see, this test will verify that the view model has some CardHolderCustomer instance in its Customer property - but not necessarily the "correct" one. Where's the value in that?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top