使用 AutoFixture Data Theories 设置 AutoMock
AutoMock setup with AutoFixture Data Theories
好的,正如我在 中的回答,AutoMoq
默认不使用 AutoFixture。这很好,通过设置和设置 ReturnsUsingFixture
.
可以轻松解决
但这可以用 Auto Fixture Data Theories 设置吗?
所以我们有一个自定义的 AutoDataAttribute,我将其称为 [MyAutoData]
。在那里我们调用并设置了一堆自定义项,例如 AutoConfiguredMoqCustomization
,将其配置为生成 webapi 控制器,并注册了许多自定义生成器。所以我们已经能够将几乎所有样板配置提取到一些基本配置文件中。我们甚至为系统测试设置了 MyAutoData
属性,所以如果你要求,比如说,一个 Id<Account>
它会使用实际的 webapi 调用和 return 创建一个新帐户一个有效的帐户 ID。
但是您如何处理设置 AutoMoq
方法 return 的问题?这是一个例子:
[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
(或它调用的 class 中)。但是对于 AutoMoq,我看不出它应该如何工作。我们不能做夹具。
有没有办法在 AutoFixture 生成项目之后但在交付给测试方法之前触发设置方法?或者有没有办法自定义 AutoMoq 行为以始终使用 .ReturnsUsingFixture(fixture)
?还是我只是在想这个问题?
IPostprocessComposer<T>.Do(Action<T>)
方法允许您在创建样本后进一步自定义样本。
在你的情况下,你可以在自定义中使用它来设置 通用方法 在 Test Double 上 return 由 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,我已经认为 AutoConfiguredMoqCustomization
对我来说太含蓄了。然而,AutoFixture 是一个社区项目,其他人发现它非常有用,可以实施它。
我认为 设计 AutoConfiguredMoqCustomization
没有任何理由不设置泛型方法;我觉得原因很简单,就是很难做到。换句话说,并不是 AutoFixture 不会 为你做那件事,而是它不能.
说了这么多,本着GOOS, I think you should listen to your tests. If the tests are difficult to write, it usually means that the SUT的精神是很难用的。这应该首先触发对 SUT 的反思,而不是测试。
您能否设计 SUT,使您不需要 此 AutoFixture 功能?
好的,正如我在 AutoMoq
默认不使用 AutoFixture。这很好,通过设置和设置 ReturnsUsingFixture
.
但这可以用 Auto Fixture Data Theories 设置吗?
所以我们有一个自定义的 AutoDataAttribute,我将其称为 [MyAutoData]
。在那里我们调用并设置了一堆自定义项,例如 AutoConfiguredMoqCustomization
,将其配置为生成 webapi 控制器,并注册了许多自定义生成器。所以我们已经能够将几乎所有样板配置提取到一些基本配置文件中。我们甚至为系统测试设置了 MyAutoData
属性,所以如果你要求,比如说,一个 Id<Account>
它会使用实际的 webapi 调用和 return 创建一个新帐户一个有效的帐户 ID。
但是您如何处理设置 AutoMoq
方法 return 的问题?这是一个例子:
[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
(或它调用的 class 中)。但是对于 AutoMoq,我看不出它应该如何工作。我们不能做夹具。
有没有办法在 AutoFixture 生成项目之后但在交付给测试方法之前触发设置方法?或者有没有办法自定义 AutoMoq 行为以始终使用 .ReturnsUsingFixture(fixture)
?还是我只是在想这个问题?
IPostprocessComposer<T>.Do(Action<T>)
方法允许您在创建样本后进一步自定义样本。
在你的情况下,你可以在自定义中使用它来设置 通用方法 在 Test Double 上 return 由 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,我已经认为 AutoConfiguredMoqCustomization
对我来说太含蓄了。然而,AutoFixture 是一个社区项目,其他人发现它非常有用,可以实施它。
我认为 设计 AutoConfiguredMoqCustomization
没有任何理由不设置泛型方法;我觉得原因很简单,就是很难做到。换句话说,并不是 AutoFixture 不会 为你做那件事,而是它不能.
说了这么多,本着GOOS, I think you should listen to your tests. If the tests are difficult to write, it usually means that the SUT的精神是很难用的。这应该首先触发对 SUT 的反思,而不是测试。
您能否设计 SUT,使您不需要 此 AutoFixture 功能?