使用AutoFixture数据理论进行AutoMock设置

时间:2015-10-21 17:59:12

标签: c# unit-testing xunit autofixture automoq

好的,正如我other question中回答的那样,AutoMoq默认情况下不使用AutoFixture。通过设置和设置ReturnsUsingFixture可以轻松解决这个问题。

但可以使用自动夹具数据理论进行设置吗?

因此我们有一个自定义的AutoDataAttribute,我将调用[MyAutoData]。在那里,我们调用并设置一组自定义项,如AutoConfiguredMoqCustomization,将其配置为生成webapi控制器,并注册许多自定义生成器。因此,我们已经能够将所有样板配置中的ALMOST提取到一些基本配置文件中。我们甚至为系统测试设置了MyAutoData属性,因此,如果您要求Id<Account>,它将使用实际的webapi调用创建新帐户并返回有效帐户ID。

但是如何设置AutoMoq方法返回呢?这是一个例子:

    [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 */
    }

在所有其他情况下,我们已经能够将此类配置移动到MyAutoData(或调用它所调用的类)。但对于AutoMoq,我无法看到它应该如何工作。我们不能做夹具。

有没有办法在AutoFixture生成项目之后但在将其传递给测试方法之前触发设置方法?或者有没有办法自定义AutoMoq行为以便始终使用.ReturnsUsingFixture(fixture)?或者我只是在想这个问题都错了?

2 个答案:

答案 0 :(得分:3)

IPostprocessComposer<T>.Do(Action<T>)方法允许您在创建之后进一步自定义标本

在您的情况下,您可以在自定义中使用它在Test Double上设置泛型方法以返回由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);
    }
}

答案 1 :(得分:3)

FWIW,我已经认为AutoConfiguredMoqCustomization对我的口味过于含蓄。但是,AutoFixture是一个社区项目,其他人发现它足以实现它。

我认为 by design AutoConfiguredMoqCustomization没有任何理由不设置泛型方法;我认为简单的原因是很难做到。换句话说,并不是说AutoFixture 不会为你做那件事,而是不能

所有这一切,本着src/gitolite-shell#L102-L108的精神,我认为你应该听你的测试。如果测试难以编写,通常意味着GOOS难以使用。这应该首先引发对SUT的反思,而不是测试。

您是否可以设计SUT以便不需要此AutoFixture功能?