2

I have the following code:

var boundArgument = new BoundArgumentOption
{
    PatientId = patientId
};

var mockRepositoryFactory = A.Fake<IRepositoryFactory>();

var sut = new HtmlOutputBuilder(mockRepositoryFactory);

var patientRecord = // Some record;

var mockRepository = A.Fake<IRepository>();
A.CallTo(() => mockRepository.Get(boundArgument)).Returns(patientRecord);
A.CallTo(() => mockRepositoryFactory.Create(boundArgument)).Returns(mockRepository);

string actualResult = sut.BuildReport(boundArgument);

actualResult.Should().Be(expectedHtmlContent);

and that passes the test.

Then I tried using AutoFixture as follows:

var fixture = new Fixture().Customize(new AutoFakeItEasyCustomization());

var boundArgument = fixture.Create<BoundArgumentOption>();

var mockRepositoryFactory = A.Fake<IRepositoryFactory>();

fixture.Freeze(mockRepositoryFactory);

var sut = fixture.Create<HtmlOutputBuilder>();

var patientRecord = //Some record;

boundArgument.PatientId = patientId;

var mockRepository = A.Fake<IRepository>();
A.CallTo(() => mockRepository.Get(boundArgument)).Returns(patientRecord);

A.CallTo(() => mockRepositoryFactory.Create(boundArgument)).Returns(mockRepository);

string actualResult = sut.BuildReport(boundArgument);

actualResult.Should().Be(expectedHtmlContent);

which fails. In particular, the patientRecord in the second instance is not getting populated properly.

What am I doing wrong here?

DavidS
  • 2,179
  • 4
  • 26
  • 44

1 Answers1

4

Note: I couldn't compile the test you provided.. however it seems that all you have to do is:

fixture.Inject(mockRepositoryFactory);

You may try the following:

[Fact]
public void TestWithAutoFixtureImperatively()
{
    // Fixture setup
    var fixture = new Fixture()
        .Customize(new AutoFakeItEasyCustomization());

    var expectedRecord = fixture.Create<string>();
    var boundArgOption = fixture.Create<BoundArgumentOption>();

    var repositoryStub = A.Fake<IRepository>();
    A.CallTo(() => 
        repositoryStub
            .Get(boundArgOption))
            .Returns(expectedRecord);

    var repositoryFactoryStub = A.Fake<IRepositoryFactory>();
    A.CallTo(() => 
        repositoryFactoryStub
            .Create(boundArgOption))
            .Returns(repositoryStub);

    fixture.Inject(repositoryFactoryStub);

    var sut = fixture.Create<HtmlOutputBuilder>();

    // Exercise system
    string result = sut.BuildReport(boundArgOption);

    // Verify outcome
    result.Should().Be(expectedRecord);

    // Teardown
}

We inject the IRepositoryFactory so that the same, injected, instance will be passed in the SUT.


Alternatively, you can also use AutoFixture declaratively with the xUnit.net extension:

[Theory, AutoDomainData]
public void TestWithAutoFixtureDeclaratively(
    string expectedRecord,
    BoundArgumentOption boundArgOption,
    Fake<IRepository> repositoryStub,
    [Frozen]Fake<IRepositoryFactory> repositoryFactoryStub,
    HtmlOutputBuilder sut)
{
    // Fixture setup
    A.CallTo(() =>
        repositoryStub
            .FakedObject
            .Get(boundArgOption))
            .Returns(expectedRecord);

    A.CallTo(() =>
        repositoryFactoryStub
            .FakedObject
            .Create(boundArgOption))
            .Returns(repositoryStub.FakedObject);

    // Exercise system
    string result = sut.BuildReport(boundArgOption);

    // Verify outcome
    result.Should().Be(expectedRecord);

    // Teardown
} 

The AutoDomainDataAttribute is defined as:

internal class AutoDomainDataAttribute : CompositeDataAttribute
{
    internal AutoDomainDataAttribute()
        : base(
            new AutoDataAttribute(
                new Fixture().Customize(
                    new AutoFakeItEasyCustomization())))
    {
    }
}
Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
Nikos Baxevanis
  • 10,868
  • 2
  • 46
  • 80
  • The code supplied was not meant to be compilable :). I wanted to get rid of fluff. Having said that the code supplied worked :). Thank you very much. I haven't seen the Inject method detailed much anywhere. Is there somewhere where I can find more information about that? Also what is the difference between Inject and Freeze? Should that be a separate question? – DavidS May 17 '13 at 18:06
  • 2
    You are welcome! `Inject` customizes the `Fixture` instance to always return the same, injected, value. `Freeze` will create the value for you and then it calls `Inject` internally. – Nikos Baxevanis May 17 '13 at 18:36
  • Details about how `Inject` works can be found at https://github.com/AutoFixture/AutoFixture/blob/master/Src/AutoFixture/FixtureRegistrar.cs#L10-75 – Nikos Baxevanis May 19 '13 at 00:53