Ok, as was answered in my other question, AutoMoq
does not use AutoFixture by default. That's fine and easily solved by doing a setup and setting ReturnsUsingFixture
.
But can that be setup with Auto Fixture Data Theories?
So we have a custom AutoDataAttribute that I'll call [MyAutoData]
. And in there we call and set up a bunch of customizations like AutoConfiguredMoqCustomization
, configuring it to produce webapi controllers, and registering a lot of custom generators. So we've been able to pull out ALMOST all of the boilerplate configuration into some basic configuration files. We've even set up the MyAutoData
attribute for system tests, so if you ask for, say, an Id<Account>
it will go and create a new account using the actual webapi calls and return a valid account id.
But how can you handle that for setting up AutoMoq
method returns? Here is an example:
[Theory, MyAutoData]
public async Task Test(Mock<ICqrsService> mockService, TheRequest request)
{
mockService.Setup(service => service.CreateAsync<TheRequest>(It.IsAny<TheRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(result); // or similar car with ReturnUsingFixture
/* now we can test */
}
In every other case, we've been able to move this kind of configuration into MyAutoData
(or into a class it calls). But for AutoMoq I can't see how it should work. We can't do a fixture.
Is there a way to trigger a setup method after AutoFixture generates an item but before it is delivered to the test method? Or is there a way to customize the AutoMoq behavior to just ALWAYS use .ReturnsUsingFixture(fixture)
? Or am I just thinking about this problem all wrong?
The IPostprocessComposer<T>.Do(Action<T>)
method allows you to further customize a specimen after it has been created.
In your case, you could use it inside a customization to setup a generic method on a Test Double to return an object created by AutoFixture:
public class FakeServiceCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<Mock<IService>>(composer =>
composer.Do(fake =>
fake.Setup(service => service.Create<Something>())
.ReturnsUsingFixture(fixture);
}
}
FWIW, I already think that AutoConfiguredMoqCustomization
is too implicit for my tastes. AutoFixture, however, is a community project, and other people found it useful enough to implement it.
I don't think there's any reason that by design AutoConfiguredMoqCustomization
doesn't set up generic methods; I think the simple reason is that it's hard to do. In other words, it's not that AutoFixture will not do that for you, but rather that it can't.
All that said, in the spirit of GOOS, I think you should listen to your tests. If the tests are difficult to write, it usually means that the SUT is difficult to use. That ought to first trigger reflection about the SUT, not the tests.
Could you design the SUT so that you don't need this AutoFixture feature?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With