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.
The current behavior of the
AutoFakeclass only works as expected (or at least, as I expected) if I make all calls toProvide<T>()before any calls toA.CallTo().Provide<T>()and the otherProvidemethods introduce a newILifetimeScopeeach time they are called. This appears to break any fakes configured viaFakeItEasy's A.CallTo()via the method described in the Autofac.Extras.FakeItEasy documentation if they were configured before the call(s) toProvide.Steps to Reproduce
This code demonstrates the problem.
If you swap the order of the calls to
A.CallTo()andProvide<T>()soProvideis 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 withA.CallTo(). I don't see anything in the documentation suggesting the two are incompatible, or anything saying I need to make sure all calls toProvide()come before any configuration viaA.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 useA.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.