Oma*_*mar 7 c# unit-testing moq xunit.net autofixture
我正在使用AutoFixture,Moq和XUnit扩展([Theory]属性),如本博客文章http://blog.ploeh.dk/2010/10/08/AutoDataTheorieswithAutoFixture中所述.
我注意到大多数单元测试看起来像这样:
[Theory, AutoMoqData]
public void Test(
[Frozen] Mock<IServiceOne> serviceOne,
[Frozen] Mock<IServiceTwo> serviceTwo,
MyClass classUnderTest)
{
// Arrange
serviceOne
.Setup(m => m.Get(It.IsAny<int>()));
serviceTwo
.Setup(m => m.Delete(It.IsAny<int>()));
// MyClass has a constructor with arguments for IServiceOne, and IServiceTwo
// classUnderTest will use the two mocks specified above
// Act
var result = classUnderTest.Foo();
// Assert
Assert.True(result);
}
Run Code Online (Sandbox Code Playgroud)
与总是装饰模具相反[Frozen],是否有办法设置夹具以始终冻结模具?
这是AutoMoqData属性:
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute()
: base(new Fixture().Customize(new AutoMoqCustomization()))
{
}
}
Run Code Online (Sandbox Code Playgroud)
虽然它目前不是内置的,但是编写一个通用的装饰器很容易,当它们离开AutoFixture树的责任时冻结对象:
public class MemoizingBuilder : ISpecimenBuilder
{
private readonly ISpecimenBuilder builder;
private readonly ConcurrentDictionary<object, object> instances;
public MemoizingBuilder(ISpecimenBuilder builder)
{
this.builder = builder;
this.instances = new ConcurrentDictionary<object, object>();
}
public object Create(object request, ISpecimenContext context)
{
return this.instances.GetOrAdd(
request,
r => this.builder.Create(r, context));
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,它装饰了另一个ISpecimenBuilder,但在返回之前记住所有值.如果同一请求再次到达,它将返回memoized值.
虽然你无法扩展 AutoMoqCustomization,但你可以复制它的作用(它只有两行代码),并使用它MemoizingBuilder周围:
public class AutoFreezeMoq : ICustomization
{
public void Customize(IFixture fixture)
{
if (fixture == null)
throw new ArgumentNullException("fixture");
fixture.Customizations.Add(
new MemoizingBuilder(
new MockPostprocessor(
new MethodInvoker(
new MockConstructorQuery()))));
fixture.ResidueCollectors.Add(new MockRelay());
}
}
Run Code Online (Sandbox Code Playgroud)
用它AutoFreezeMoq代替AutoMoqCustomization.它将冻结所有模拟,以及从这些模拟创建的所有接口和抽象基类.
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute()
: base(new Fixture().Customize(new AutoFreezeMoq()))
{
}
}
Run Code Online (Sandbox Code Playgroud)