Hi,
I'm trying to get the instance of the the inner Mocked Interface created by AutoMoqData to setup the interface.
Is there a way to do something like this
[Theory, AutoMoqData]
public void Dummy(IFixture fixture, ComplexClassWithInnerInterface sut)
{
fixture.GetInstance<IInnerInterfaceMockCreatedByAutoMoqData>().Setup(x => x.Method).Result(something);
Assert.Equal(String.Empty, String.Empty);
}
Thanks
try
Mock.Get(sut).Setup(x => x.Method).Result(something);
You will get Object instance was not created by Moq. accessing sut.
This will actually work if interface is in a public property.
Mock.Get(sut.InnerInterface).Setup(x => x.Method).Result(something);
But what if the interface is is mocked and constructor injected, registered in the IoC container but not accessible in sut with a public property?
In this case you'll have to freeze the mock to ensure that the instance you generate will also be injected into the sut:
[Theory, AutoMoqData]
public void Dummy(
IFixture fixture,
[Frozen]Mock<YourInnerInterface> innerInterfaceMock,
ComplexClassWithInnerInterface sut)
{
innerInterfaceMock.Setup(x => x.Method).Result(something);
sut.DoSomething();
Assert.Equal(String.Empty, String.Empty);
}
Be careful to always create the frozen mocks before the sut so that they already exist when the sut gets created and therefore get correctly injected.
See ploeh'sblog for reference.
Hi,
I was already doing that. But for 30 interfaces it's pretty ugly to have them in method parameters.
Your code reminded me that AutoMoqData does not freeze all mocked interfaces. So it seems impossible to get auto created mocks from the container of the fixture. They are not injected by default so if fixture had a GetInstance like method, it will not return anything for the auto created mocks. That's why I get duplicates if I freeze the mock with the fixture instance. The only way I see It would work is if the sut could be updated with the later frozen mocks, but that would be ugly. The easy way is to use AutoMoqData to create the IFixture, freeze and setup mocks in the test method, then create sut. With this setup I can create a reusable helper method to freeze and setup mocks.
Thanks
Thanks @xlecoustillier for the great answer. Basically, I'd suggest to do the same as I'm constantly following this pattern in my tests.
But for 30 interfaces it's pretty ugly to have them in method parameters.
Well, this argument looks a bit weird. Probably, it's something wrong with the design of tested code if you need to configure 30 dependencies to make a scenario 😟 I'm 99% @ploeh would suggest you to review the code first before proceeding further, as per his advice it's recommended to have max 3-4 dependencies 😅
So it seems impossible to get auto created mocks from the container of the fixture. They are not injected by default so if fixture had a GetInstance like method, it will not return anything for the auto created mocks.
I'm not 100% sure I understood the entire message clearly, but from what I got you are right. By default all the generated objects are transient and fixture
doesn't preserve them. If you wish to make the particular object a singleton, you should use the fixture.Freeze<>()
API or [Frozen]
attribute or any other suitable API.
The existing default behavior was designed to cover the common scenarios and in most cases you _don't want_ to have the same object per type.
If you are still looking for the help from our side, please provide more exact requirement you have. Better, share enough code to demonstrate the current limitations and goal you would like to achieve - that will help to sync better 😉
Thanks.
Yes, I would suggest that 30 dependencies are too many.
Regarding getting at the injected dependencies, using the [Frozen]
attribute, as @xlecoustillier suggests, is one option, and in fact the reason that attribute originally exists.
Using Mock.Get(sut.Dep1)
is also an option I often use.
But what if the interface is [...] constructor injected [...] but not accessible in sut with a public property?
Why not expose it as a property, then? What you compose, you can also expose.. It doesn't break encapsulation to expose it.
I feel like adding on @ploeh by specifying that the best approach is to expose dependencies as class properties without enriching your abstraction which would be nothing more that leaking your implementation!
@malylemire1 Closing this as it seems no further assistance is required. Please let us know if there is anything else we can help you with 😉
Thanks for one more time for raising the question! 👍
Most helpful comment
Thanks @xlecoustillier for the great answer. Basically, I'd suggest to do the same as I'm constantly following this pattern in my tests.
Well, this argument looks a bit weird. Probably, it's something wrong with the design of tested code if you need to configure 30 dependencies to make a scenario 😟 I'm 99% @ploeh would suggest you to review the code first before proceeding further, as per his advice it's recommended to have max 3-4 dependencies 😅
I'm not 100% sure I understood the entire message clearly, but from what I got you are right. By default all the generated objects are transient and
fixture
doesn't preserve them. If you wish to make the particular object a singleton, you should use thefixture.Freeze<>()
API or[Frozen]
attribute or any other suitable API.The existing default behavior was designed to cover the common scenarios and in most cases you _don't want_ to have the same object per type.
If you are still looking for the help from our side, please provide more exact requirement you have. Better, share enough code to demonstrate the current limitations and goal you would like to achieve - that will help to sync better 😉
Thanks.