Skip to content

Provide() introduces a new scope, which causes behavior configured via A.CallTo() to fail to work as expected #22

@katiejanekilian

Description

@katiejanekilian

The current behavior of the AutoFake class only works as expected (or at least, as I expected) if I make all calls to Provide<T>() before any calls to A.CallTo().

Provide<T>() and the other Provide methods introduce a new ILifetimeScope each time they are called. This appears to break any fakes configured via FakeItEasy's A.CallTo() via the method described in the Autofac.Extras.FakeItEasy documentation if they were configured before the call(s) to Provide.

Steps to Reproduce

This code demonstrates the problem.

public interface IStringService { string GetString(); }

public static void ACallTo_before_Provide()
{
    using (var fake = new AutoFake())
    {
        A.CallTo(() => fake.Resolve<IStringService>().GetString())
            .Returns("Test string");

        fake.Provide(new StringBuilder());
        
        var stringService = fake.Resolve<IStringService>();
        string result = stringService.GetString();

        // FAILS. The result should be "Test string",
        // but instead it's an empty string.
        Assert.Equal($"Test string", result);
    }
}

If you swap the order of the calls to A.CallTo() and Provide<T>() so Provide is called first, it works as expected.

Expected Behavior

I would expect the order I configure dependences not to matter in the unit tests. I think this is a bug? I opened a question on StackOverflow; @blairconrad replied, but wasn't sure if this is the correct behavior or not.

It seems to me it won't always be possible to call Provide() before I configure objects with A.CallTo(). I don't see anything in the documentation suggesting the two are incompatible, or anything saying I need to make sure all calls to Provide() come before any configuration via A.CallTo().

Dependency Versions

Autofac 6.2.0
Autofac.Extras.FakeItEasy 7.0.0
FakeItEasy 7.1.0

Additional Info

Here is a GitHub repository demonstrating the problem in more detail. It demonstrates that dependencies can be configured in any order if you solely use Provide(), or if you solely use A.CallTo(). Only if you mix the two does the order becomes important, furthering my suspicion that this is a bug.

Also, in case it helps, @blairconrad found that the stacked scope behavior causing this problem was introduced in PR 18. He wasn't sure why.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions