为什么AutoFixture执行不止一次?

时间:2017-09-10 13:31:47

标签: c# static nunit autofixture

我已经使用AutoFixture / AutoMoqData / Nunit好几个月了,到目前为止很开心。

但我陷入了一些奇怪的事情:

如果我想在测试套件中运行单个测试(使用TestDriven),似乎AutoMoqData属性多次启动(5到9之间,但我不知道为什么,以及决定了多少它运行的时间。)

问题在于,如果我尝试在AutoFixture自定义项中冻结对象实例,它将使用这么多的fixture实例冻结5到9个对象,并且不知道在我的测试中注入了哪一个。< / p>

有没有办法避免这种情况?为什么会在第一时间发生?

示例代码:

public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute()
        : base(new Fixture()
            .Customize(new AutoMoqCustomization())
            .Customize(new FrozenFooCustomization()) // freezing an object
            .Customize(new FrozenFixtureCustomization()) // freezing the passed fixture to have the fixture instance available in the test body
            .Customize(new StaticBindingCustomization()) // binding the frozen object to a static reference
            )
    {
    }
}

public class FrozenFooCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Freeze<Foo>();
    }
}

public class Foo { }

public class FrozenFixtureCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Inject(fixture);
    }
}

public class StaticBindingCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Freeze<Mock<ISomeUtilities>>();
        var someUtilities = fixture.Create<Mock<ISomeUtilities>>();
        someUtilities.Setup(x => x.GetStuff()).Returns(fixture.Create<Foo>());
        // this is executed several times, each time with a different instance of fixture, returning a different instance of Foo
        SomeExtensions.Factory = x => someUtilities.Object;
        // so the last "someUtilities.Object" is bound to the factory, but the test relies on a frozen version generated by one of the previous fixture instances
    }
}

[TestFixture]
public class Test
{
    [Test, AutoMoqData]
    public void SomeTest(
        [Frozen]Mock<ISomeUtilities> objMock,
        SomeObjectToTest sut)
    {
        Assert.IsTrue(ReferenceEquals(objMock.Object.GetStuff(), sut.GetStuff()));
    }
}

public class SomeObjectToTest { }

public static class SomeExtensions
{
    public static Func<object, ISomeUtilities> Factory { get; set; } = x => new SomeUtilities(x);

    public static object GetStuff(this object obj)
    {
        return Factory(obj).GetStuff();
    }
}

public class SomeUtilities : ISomeUtilities
{
    private readonly object _obj;

    public SomeUtilities(object obj)
    {
        _obj = obj;
    }

    public object GetStuff()
    {
        return _obj; // whatever
    }
}

public interface ISomeUtilities
{
    object GetStuff();
}

编辑:SomeExtensions.Factory是一个工厂,用于根据Daniel Cazzulino's approach使扩展可模拟。

我不是那些扩展的忠实粉丝,并希望在某些时候重构它们,但这是另一次。这里的问题是为什么有几个夹具实例,使得工厂中使用的冻结SomeUtilities模拟不同于测试中使用的模拟实例,因此测试失败。

EDIT2:根据@MarkSeemann的建议,我在Autofixture repo报告了一个问题。

0 个答案:

没有答案