使用私有 ctor 和静态创建方法和私有 id 属性模拟类
本文关键字:id 属性 模拟类 方法 创建 ctor 静态 | 更新日期: 2023-09-27 17:56:29
我正在尝试使用AutoFixture来简化我的生活。
我如何模拟课程
- 非公共构造函数和
- 非公共 ID 和
- 静态"创建"方法?
例
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;
}
}
我尝试使用工厂和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();
}
跟
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);
}
}
演示 C# 解决方案可在 https://github.com/draptik/MockingStaticCreate
感谢任何指示,
帕特里克
AF
将做正确的事情(User.Create()
使用匿名名称arg),没有任何自定义。
唯一缺少的位是设置Id
。这是您必须自己回答的问题 - 您的消费代码首先应该如何做到这一点?当你决定后,你可以做fixture.Customize<User>( c => c.FromFactory( User.Create).Do( x => ???)
也许您可以考虑公开一个也需要id
的 ctor。然后你可以做一个Customize<User>
... GreedyConstructorQuery
.
如果你的ORM正在做一些古怪的反思,而你喜欢这样和/或无法绕过它,你可以选择是否应该为你的测试:
a) 也这样做 - 如果这与给定的测试或一组测试相关
b) 认为这是行之有效的
关于混合模拟和将值输入到实体或值对象 - 不要这样做(Mark Seemann 的命令与查询文章可能会在这里为您提供帮助)。您似乎需要/想要这样做的事实使您似乎在单个测试中过于雄心勃勃 - 您是否找到了最简单的测试内容,并尝试用最少的设置进行单一Assert
测试一件事。
去买GOOS的书吧——它能帮助你找到平衡这些权衡的方法。