如何使用FakeItEasy使用AutoFixture注册未明确定义为严格的依赖关系?
作者:互联网
当我需要测试具有许多依赖关系的类时,我将AutoFixture与FakeItEasy一起使用,但是我只想模拟其中的一些.所有其他依赖项我都喜欢使用FakeItEasy的Strict()选项进行模拟.为了使测试更加简洁,我想仅模拟所需的依赖项,并能够指定所有不模拟的依赖项都是使用Strict()创建的.
在下面的示例中,我希望能够删除创建IDependency2的模拟的两行代码,但保持相同的行为:如果被测类访问IDependency2的任何方法,则将引发异常.
任何想法如何做到这一点?
[TestFixture]
public class AutoTests
{
[Test]
public void Test()
{
// Arrange
IFixture fixture = new Fixture().Customize(new AutoFakeItEasyCustomization());
var dependency1 = fixture.Freeze<IDependency1>();
A.CallTo(() => dependency1.DoSomething()).Returns(12);
// I do not want to specify these two lines
var dependency2 = A.Fake<IDependency2>(s=>s.Strict());
fixture.Register(() => dependency2);
// Act
var classUnderTest = fixture.Create<ClassUnderTest>();
var actualResult = classUnderTest.MethodUnderTest();
// Assert
Assert.That(actualResult,Is.GreaterThan(0));
}
}
public class ClassUnderTest
{
private readonly IDependency1 _dependency1;
private readonly IDependency2 _dependency2;
public ClassUnderTest(IDependency1 dependency1, IDependency2 dependency2)
{
_dependency1 = dependency1;
_dependency2 = dependency2;
}
public int MethodUnderTest()
{
return _dependency1.DoSomething()
+ _dependency2.DoSomething();
}
}
public interface IDependency1
{
int DoSomething();
}
public interface IDependency2
{
int DoSomething();
}
解决方法:
作为权衡解决方案,实现自定义ISpecimenBuilder使其具有所有自动生成的伪造品作为严格伪造品是非常简单的.您可以查看标准的Ploeh.AutoFixture.AutoFakeItEasy.FakeItEasyRelay假货生成器,以了解幕后发生的情况.修改后的严格假货定制构建器实现如下:
public class FakeItEasyStrictRelay : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
throw new ArgumentNullException("context");
if (!this.IsSatisfiedBy(request))
return new NoSpecimen(request);
var type = request as Type;
if (type == null)
return new NoSpecimen(request);
var fakeFactoryMethod = this.GetType()
.GetMethod("CreateStrictFake", BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod((Type) request);
var fake = fakeFactoryMethod.Invoke(this, new object[0]);
return fake;
}
public bool IsSatisfiedBy(object request)
{
var t = request as Type;
return (t != null) && ((t.IsAbstract) || (t.IsInterface));
}
private T CreateStrictFake<T>()
{
return A.Fake<T>(s => s.Strict());
}
}
只需使用以下语句进行注册:
IFixture fixture = new Fixture().Customize(
new AutoFakeItEasyCustomization( new FakeItEasyStrictRelay()));
标签:fakeiteasy,autofixture,unit-testing,c 来源: https://codeday.me/bug/20191121/2048533.html