是否有某种方法让AutoFixture使用内部setter创建属性?
我查看了AutoFixture源代码,发现在AutoPropertiesCommand中,GetProperties方法检查属性是否具有GetSetMethod()!= null。 除非将ignorePublic参数设置为true,否则使用内部setter将返回null。
最简单的事情就是让公司成员公开,但在项目中,我正在努力解决这个问题,这不是正确的解决方案。
以下是项目中的一段简化代码。
public class Dummy
{
public int Id { get; set; }
public string Name { get; internal set; }
}
public class TestClass
{
[Fact]
public void Test()
{
var dummy = new Fixture().Create<Dummy>();
Assert.NotNull(dummy.Name);
}
}
答案 0 :(得分:4)
理想情况下,测试不应该与类的internal
成员进行交互,因为它们是从其公共API中明确排除的。相反,这些成员将通过公共API启动的代码路径间接进行测试。
但是,如果在您的特定情况下这不可行,则可能的解决方法是从测试中明确地将值分配给内部属性。
您可以通过以下两种方式之一来实现:
InternalsVisibleTo
属性将程序集中的所有内部成员公开给测试项目。在您的示例中,选项1将是:
// [assembly:InternalsVisibleTo("Tests")]
// is applied to the assembly that contains the 'Dummy' type
[Fact]
public void Test()
{
var fixture = new Fixture();
var dummy = fixture.Create<Dummy>();
dummy.Name = fixture.Create<string>();
// ...
}
选项2,取而代之的是:
public class Dummy : IModifiableDummy
{
public string Name { get; private set; }
public void IModifiableDummy.SetName(string value)
{
this.Name = value;
}
}
[Fact]
public void Test()
{
var fixture = new Fixture();
var dummy = fixture.Create<Dummy>();
((IModifiableDummy)dummy).SetName(fixture.Create<string>());
// ...
}
选项1的实施起来相当快,但是在装配体中打开所有内部成员的副作用可能不是您想要的。
另一方面,选项2允许您控制对象状态的哪些部分应该被公开为可修改,同时仍然将它与对象自己的公共API分开。
作为旁注,我想指出,因为你正在使用xUnit,你可以利用AutoFixture的support for Data Theories来让你的测试更加简洁:
[Theory, AutoData]
public void Test(Dummy dummy, string name)
{
((IModifiableDummy)dummy).SetName(name);
// ...
}
如果您希望将Name
属性设置为已知值,同时仍保持Dummy
对象的其余部分匿名,则还可以{{3在相同的数据理论中:
[Theory, InlineAutoData("SomeName")]
public void Test(string name, Dummy dummy)
{
((IModifiableDummy)dummy).SetName(name);
// ...
}