其他分享
首页 > 其他分享> > 如何使用FakeItEasy使用AutoFixture注册未明确定义为严格的依赖关系?

如何使用FakeItEasy使用AutoFixture注册未明确定义为严格的依赖关系?

作者:互联网

当我需要测试具有许多依赖关系的类时,我将AutoFixture与FakeItEasy一起使用,但是我只想模拟其中的一些.所有其他依赖项我都喜欢使用FakeItEasy的Strict()选项进行模拟.为了使测试更加简洁,我想仅模拟所需的依赖项,并能够指定所有不模拟的依赖项都是使用Strict()创建的.

在下面的示例中,我希望能够删除创建IDependency2的模拟的两行代码,但保持相同的行为:如果被测类访问IDependency2的任何方法,则将引发异常.

任何想法如何做到这一点?

[TestFixture]
public class AutoTests
{
    [Test]
    public void Test()
    {
        // Arrange
        IFixture fixture = new Fixture().Customize(new AutoFakeItEasyCustomization());

        var dependency1 = fixture.Freeze<IDependency1>();
        A.CallTo(() => dependency1.DoSomething()).Returns(12);

        // I do not want to specify these two lines
        var dependency2 = A.Fake<IDependency2>(s=>s.Strict());
        fixture.Register(() => dependency2);

        // Act
        var classUnderTest = fixture.Create<ClassUnderTest>();
        var actualResult = classUnderTest.MethodUnderTest();

        // Assert
        Assert.That(actualResult,Is.GreaterThan(0));
    }
}

public class ClassUnderTest
{
    private readonly IDependency1 _dependency1;
    private readonly IDependency2 _dependency2;

    public ClassUnderTest(IDependency1 dependency1, IDependency2 dependency2)
    {
        _dependency1 = dependency1;
        _dependency2 = dependency2;
    }

    public int MethodUnderTest()
    {
        return _dependency1.DoSomething() 
            + _dependency2.DoSomething();
    }
}

public interface IDependency1
{
    int DoSomething();
}

public interface IDependency2
{
    int DoSomething();
}

解决方法:

作为权衡解决方案,实现自定义ISpecimenBuilder使其具有所有自动生成的伪造品作为严格伪造品是非常简单的.您可以查看标准的Ploeh.AutoFixture.AutoFakeItEasy.FakeItEasyRelay假货生成器,以了解幕后发生的情况.修改后的严格假货定制构建器实现如下:

    public class FakeItEasyStrictRelay : ISpecimenBuilder
    {
        public object Create(object request, ISpecimenContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");

            if (!this.IsSatisfiedBy(request))
                return new NoSpecimen(request);

            var type = request as Type;
            if (type == null)
                return new NoSpecimen(request);

            var fakeFactoryMethod = this.GetType()
                .GetMethod("CreateStrictFake", BindingFlags.Instance | BindingFlags.NonPublic)
                .MakeGenericMethod((Type) request);

            var fake = fakeFactoryMethod.Invoke(this, new object[0]);

            return fake;
        }

        public bool IsSatisfiedBy(object request)
        {
            var t = request as Type;
            return (t != null) && ((t.IsAbstract) || (t.IsInterface));
        }

        private T CreateStrictFake<T>()
        {
            return A.Fake<T>(s => s.Strict());
        }
    }

只需使用以下语句进行注册:

 IFixture fixture = new Fixture().Customize(
                new AutoFakeItEasyCustomization( new FakeItEasyStrictRelay()));

标签:fakeiteasy,autofixture,unit-testing,c
来源: https://codeday.me/bug/20191121/2048533.html