How to register dependencies that are not explicitly defined as Strict using AutoFixture with FakeItEasy?

I use AutoFixture with FakeItEasy when I need to test a class with many dependencies, but I decided to mock some of them. All other dependencies I prefer to mock with the Strict () FakeItEasy option. To make my test cleaner, I would like to mock only the dependencies I want and be able to specify that all dependencies that do not mock creation are created with Strict ().

In the example below, I would like to remove two lines of code that create the layout of IDependency2 but retain the same behavior: if the class under test calls any method on IDependency2, an exception will be thrown.

Any idea how to do this?

[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();
}

      

+3


source to share


1 answer


As a compromise solution, it is quite easy to implement a custom ISpecimenBuilder so that all auto- generated fakes are strict fakes. You can take a look at the standard Ploeh.AutoFixture.AutoFakeItEasy.FakeItEasyRelay fake builder to understand what's going on behind the curtain. The modified custom builder for strict forgeries is implemented as follows:

    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());
        }
    }

      



It can simply be registered with the following expression:

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

      

+3


source







All Articles