10

Is is possible to have ITestOutputHelper created by xUnit to be available in AutoFixture context?

In my integration tests I use Builder class that contains helper methods for some routine operations. In order to hide complexity of class creation I use custom AutoDataAttribute, so my tests are getting created object as test method parameter from AutoFixture.

Now I decided to add some logging functionality to Builder and can't find out how to pass ITestOutputHelper into Builder constructor from custom AutoDataAttribute.

using Ploeh.AutoFixture;
using Ploeh.AutoFixture.AutoNSubstitute;
using Ploeh.AutoFixture.Xunit2;
using Xunit;
using Xunit.Abstractions;

namespace XunitAutoFixtItestOutput
{
    public class Class1Tests
    {
        private readonly ITestOutputHelper _output;

        public Class1Tests(ITestOutputHelper output)
        {
            _output = output;
        }

        [Theory, DefaultAutoData]
        public void UnitOfWork_StateUnderTest_ExpectedBehavior(Builder builder)
        {
        }
    }

    public class Builder
    {
        private readonly ITestOutputHelper _outputHelper;

        public Builder(ITestOutputHelper outputHelper)
        {
            _outputHelper = outputHelper;
        }

        public void DoSomething()
        {
            _outputHelper.WriteLine("Something happened");
        }
    }

    public class DefaultAutoData : AutoDataAttribute
    {
        public DefaultAutoData() : base(new Fixture().Customize(new DefaultCustomization()))
        {
            this.Fixture.Customize<Builder>(f => f.FromFactory(new Builder(??Where to get it from??)));
        }
    }

    public class DefaultCustomization : CompositeCustomization
    {
        public DefaultCustomization() : base(new AutoConfiguredNSubstituteCustomization())
        {
        }
    }
}
Michael Baranov
  • 789
  • 1
  • 7
  • 17
  • 2
    xUnit.net controls the lifetime of the test classes, as well as it creates the `ITestOutputHelper` instance that gets passed to the test class' constructor. I don't have the full view of what xUnit.net's API enables you to do, but unless it provides an extensibility point that enables you to get the injected `ITestOutputHelper` when `DataAttribute.GetData` is invoked, I don't think this is possible... – Mark Seemann Feb 11 '17 at 22:07
  • Thank you for information, will have a look at DataAttribute. – Michael Baranov Feb 12 '17 at 20:59
  • @MichaelBaranov have you managed to find any solution to it? – Andrii Litvinov Oct 15 '19 at 08:17

2 Answers2

3

As Mark Seemann foresaw in the comments, it's not supported in the current version (v2.1) and there is no visible extensibility point. Therefore, it might be added in future versions.

There is a suggestion to sacrifice the AutoData attribute (at least until xUnit is extended) and configure fixture in the test constructor:

public class Class1Tests
{
  private readonly Fixture fixture;

  public Class1Tests(ITestOutputHelper output)
  {
    this.fixture = new Fixture();
    this.fixture.Inject(output);
  }

  [Fact]
  public void UnitOfWork_StateUnderTest_ExpectedBehavior()
  {
    var builder = this.fixture.Create<Builder>();
    builder.DoSomething();
  }
}
Serhii Shushliapin
  • 2,528
  • 2
  • 15
  • 32
1

You can add the xUnit.DependencyInjection NuGet package to your project, and then take the ITestOutputHelperAccessor into your Fixture constructor. It has just one property, Output. That is the ITestOutputHelper for the current test. However, it's of limited use because your fixture is called before and after the tests have been run. So there is no test output while your fixture code is executing.

carlin.scott
  • 6,214
  • 3
  • 30
  • 35