如何在 AutoDataAttribute sub类 中创建 Mock 类?
How to create Mock classes in AutoDataAttribute subclasses?
我目前有一个名为 ExampleViewModelAttribute 的 class,它派生自 TestViewModelDataAttribute,后者 class 派生自 AutoDataAttribute class。
public class TestViewModelDataAttribute : AutoDataAttribute
{
public TestViewModelDataAttribute()
: this(new Fixture())
{
}
public TestViewModelDataAttribute(IFixture fixture)
: base(fixture)
{
Fixture.Customize(new ViewModelsCustomization());
Fixture.Inject(Fixture);
}
}
public class ExampleViewModelAutoDataAttribute : TestViewModelAutoDataAttribute
{
public ExampleViewModelAutoDataAttribute()
{
var someExampleMock = Fixture.Create<Mock<ISomeExampleMock>>();
Fixture.Inject(someExampleMock);
}
}
我的问题是,我不断收到警告“夹具是为了提高性能效率而延迟创建的,因此这个 属性 已被弃用,因为它会立即激活夹具。” +
“如果您需要自定义夹具,请在传递给构造函数的工厂方法中执行此操作。”
如何修复此警告?我想在夹具中注入模拟 classes,我只得到一个答案可以帮助我修复基础 class 警告,但我还需要修复注入模拟 classes。
修复基础 class
public class TestViewModelDataAttribute : AutoDataAttribute
{
public TestViewModelDataAttribute() : base(() =>
{
var fixture = new Fixture().Customize(new CompositeCustomization(
new AutoMoqCustomization(),
new SupportMutableValueTypesCustomization()));
return fixture;
})
{
}
}
这是我从以下答案中得到的 When setting up a custom AutoDataAttribute for auto mocking, what's the proper syntax to tell AutoFixture to ignore all recursive structures?
但是由于我在派生的 class 中使用了 属性 的 Fixture,我仍然会出错。我应该如何解决这个问题?
谢谢
您不应使用 AutoDataAttribute
中的 Fixture
属性,它可能会在版本 5 中被删除。
如果您尝试在将模拟注入测试之前设置模拟,您可以尝试创建一个定制来执行此操作。
public class MockValuesSetupCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
var myMock = fixture.Freeze<Mock<ISomeExampleMock>>();
myMock.Setup(x => x.DoSomething()).Returns("something");
}
}
当您自定义自动数据属性时,您可以使用此自定义来自定义夹具。
public class TestViewModelDataAttribute : AutoDataAttribute
{
public TestViewModelDataAttribute()
: base(() => new Fixture()
.Customize(
new CompositeCustomization(
new AutoMoqCustomization(),
new SupportMutableValueTypesCustomization(),
new MockValuesSetupCustomization())))
{
}
}
如果你只是需要一些依赖来解析 Mock<ISomeExampleMock>
那么你不需要做任何事情,因为 AutoMoqCustomization
会自动为任何接口创建模拟。
然后,您可以通过在测试方法参数中冻结它们来访问这些注入的模拟。
假设您使用的是 xUnit,您的测试将如下所示。
[Theory]
[TestViewModelData]
public void ShouldReturnExpectedResult(
[Frozen] Mock<ISomeExampleMock> someExampleMock,
ClassUnderTest sut)
{
sut.DoStuff();
someExampleMock.Verify(x => x.DoSomething(), Times.Once);
}
我目前有一个名为 ExampleViewModelAttribute 的 class,它派生自 TestViewModelDataAttribute,后者 class 派生自 AutoDataAttribute class。
public class TestViewModelDataAttribute : AutoDataAttribute
{
public TestViewModelDataAttribute()
: this(new Fixture())
{
}
public TestViewModelDataAttribute(IFixture fixture)
: base(fixture)
{
Fixture.Customize(new ViewModelsCustomization());
Fixture.Inject(Fixture);
}
}
public class ExampleViewModelAutoDataAttribute : TestViewModelAutoDataAttribute
{
public ExampleViewModelAutoDataAttribute()
{
var someExampleMock = Fixture.Create<Mock<ISomeExampleMock>>();
Fixture.Inject(someExampleMock);
}
}
我的问题是,我不断收到警告“夹具是为了提高性能效率而延迟创建的,因此这个 属性 已被弃用,因为它会立即激活夹具。” + “如果您需要自定义夹具,请在传递给构造函数的工厂方法中执行此操作。”
如何修复此警告?我想在夹具中注入模拟 classes,我只得到一个答案可以帮助我修复基础 class 警告,但我还需要修复注入模拟 classes。
修复基础 class
public class TestViewModelDataAttribute : AutoDataAttribute
{
public TestViewModelDataAttribute() : base(() =>
{
var fixture = new Fixture().Customize(new CompositeCustomization(
new AutoMoqCustomization(),
new SupportMutableValueTypesCustomization()));
return fixture;
})
{
}
}
这是我从以下答案中得到的 When setting up a custom AutoDataAttribute for auto mocking, what's the proper syntax to tell AutoFixture to ignore all recursive structures?
但是由于我在派生的 class 中使用了 属性 的 Fixture,我仍然会出错。我应该如何解决这个问题? 谢谢
您不应使用 AutoDataAttribute
中的 Fixture
属性,它可能会在版本 5 中被删除。
如果您尝试在将模拟注入测试之前设置模拟,您可以尝试创建一个定制来执行此操作。
public class MockValuesSetupCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
var myMock = fixture.Freeze<Mock<ISomeExampleMock>>();
myMock.Setup(x => x.DoSomething()).Returns("something");
}
}
当您自定义自动数据属性时,您可以使用此自定义来自定义夹具。
public class TestViewModelDataAttribute : AutoDataAttribute
{
public TestViewModelDataAttribute()
: base(() => new Fixture()
.Customize(
new CompositeCustomization(
new AutoMoqCustomization(),
new SupportMutableValueTypesCustomization(),
new MockValuesSetupCustomization())))
{
}
}
如果你只是需要一些依赖来解析 Mock<ISomeExampleMock>
那么你不需要做任何事情,因为 AutoMoqCustomization
会自动为任何接口创建模拟。
然后,您可以通过在测试方法参数中冻结它们来访问这些注入的模拟。
假设您使用的是 xUnit,您的测试将如下所示。
[Theory]
[TestViewModelData]
public void ShouldReturnExpectedResult(
[Frozen] Mock<ISomeExampleMock> someExampleMock,
ClassUnderTest sut)
{
sut.DoStuff();
someExampleMock.Verify(x => x.DoSomething(), Times.Once);
}