dra*_*tik 4 c# unit-testing mocking autofixture fakeiteasy
我正在尝试使用 AutoFixture 来简化我的生活。
我如何模拟一个班级
例子
public class User
{
private User(){}
/// <summary>
/// Created by Database...
/// </summary>
public long? Id { get; protected set; }
public string Name { get; protected set; }
public static User Create(string name)
{
var user = new User {Name = name};
return user;
}
}
Run Code Online (Sandbox Code Playgroud)
我试过使用 Factory 和 SpecimenBuilder 的组合:
[Fact]
public void CreatingUserWithId_Should_Work_UsingFactoryAndSpecimenBuilder()
{
IFixture fixture = new Fixture().Customize(new AutoFakeItEasyCustomization());
fixture.Customizations.Add(new UserBuilder());
fixture.Customize<User>(o => o.FromFactory(() => User.Create("foo")));
var user = fixture.Create<User>();
user.Should().NotBeNull();
user.Id.Should().HaveValue();
}
Run Code Online (Sandbox Code Playgroud)
和
public class UserBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var pi = request as PropertyInfo;
if (pi == null) return new NoSpecimen(request);
// The following code only works for public properties... :-(
if (pi.Name == "Id" && pi.PropertyType == typeof (long?)) return 42;
return new NoSpecimen(request);
}
}
Run Code Online (Sandbox Code Playgroud)
演示 C# 解决方案可在https://github.com/draptik/MockingStaticCreate 获得
感谢任何指点,
帕特里克
AF 将做正确的事情(User.Create()
使用匿名名称 arg),无需任何自定义。
唯一缺少的位是设置Id
. 这是一个您必须自己回答的问题——您的消费代码首先应该如何做到这一点?当你决定后,你可以做fixture.Customize<User>( c => c.FromFactory( User.Create).Do( x => ???)
也许你可以考虑暴露一个也需要一个的ctor id
。然后,你可以做一个Customize<User>
... GreedyConstructorQuery
。
如果您的 ORM 正在做一些古怪的反射并且您喜欢它和/或无法绕过它,您可以选择是否应该为您的测试:
a)也这样做 - 如果这与给定的测试或测试集相关
b) 认为这是可行的
关于将模拟和值混合到实体或值对象中 - 不要这样做(Mark Seemann 的命令与查询文章可能对您有所帮助)。您似乎需要/想要这样做的事实使您似乎在个别测试中试图过于雄心勃勃 - 您是否正在寻找最简单的测试方法并尝试以Assert
最少的设置进行单一测试。
去购买GOOS 的书——它会帮助你找到平衡这些权衡的方法。