C# 如何使用AutoFixture.CreateAnonymous<&燃气轮机;()在具有内部ctor的类上
我做了如下的事情C# 如何使用AutoFixture.CreateAnonymous<&燃气轮机;()在具有内部ctor的类上,c#,unit-testing,autofixture,C#,Unit Testing,Autofixture,我做了如下的事情 public class Foo { public Bar { get; set; } } public class Bar { internal Bar(string id) {} } public static class Bars { public static class TypeOne { public static readonly SimpleBar = new Bar("id-for-type
public class Foo
{
public Bar { get; set; }
}
public class Bar
{
internal Bar(string id)
{}
}
public static class Bars
{
public static class TypeOne
{
public static readonly SimpleBar = new Bar("id-for-type1-simple-bar");
}
}
现在,我在我的单元测试组件中添加了一个InternalsVisibleTo
,以便能够访问内部条形图,然后我做了:
var fixture = new Fixture();
fixture.Register(() => new Bar(fixture.CreateAnonymous<string>()));
var foo = fixture.CreateAnonymous<Foo>();
var fixture=newfixture();
fixture.Register(()=>新条(fixture.CreateAnonymous());
var foo=fixture.CreateAnonymous();
问题:这是使用AutoFixture的“正确”方法还是有更好的方法 你就不能这样做吗
fixture.Inject(Bars.TypeOne.SimpleBar);
这都是公开的。不需要InternalsVisibleTo,我认为…这段代码可以工作,因为您已经有了一个引用Bar的公共静态类,这段代码不需要设置
InternalsVisibleTo
属性
var fixture = new Fixture().Customize(new AutoMoqCustomization());
fixture.Inject(Bars.TypeOne.SimpleBar);
var sut = fixture.CreateAnonymous<Foo>();
sut.Should().NotBeNull();
sut.Bar.Should().NotBeNull();
sut.Bar.Should().Be(Bars.TypeOne.SimpleBar);
var fixture=newfixture().Customize(新的AutoMoqCustomization());
夹具。注入(棒。类型一。SimpleBar);
var sut=fixture.CreateAnonymous();
sut.Should().NotBeNull();
sut.Bar.Should().NotBeNull();
sut.Bar.Should().Be(Bar.TypeOne.SimpleBar);
永远不要走内部可视的道路
-不要让我开始列表,但它从系统的每个部分开始,包括所有测试助手
如果你绝对不能(仔细思考它)——大多数时候你把内部设备放在一个名字空间中,你就不会把它的一部分考虑成一个命名空间,这样它们就不会杂乱任何东西——例如XUndo.SDK和各种<代码>。我已经为我的雇主使用了内部< /代码>子命名空间,那么,管理这种只为测试而暴露的内容的正确方法就是。注意,它之所以有一个名称,是因为它(正确地)在中被称为反模式
现在,回答你的问题
InternalsVisibleTo
DEBUG
?)版本中公开的工厂(但理想情况下,您可以在另一个命名空间中无条件地公开):
然后像这样使用它:
#if INCLUDE_FOR_TEST_ONLY
public class Facts
{
[Fact]
public void Fact()
{
Fixture fixture = new Fixture();
fixture.Register( ( string name ) => BarsForTestOnly.Create( name ) );
var anonymousBar = fixture.CreateAnonymous<Bar>();
}
[Fact]
public void FactSyntax2() // Just a variant of Fact above
{
Fixture fixture = new Fixture();
fixture.Register<string, Bar>( BarsForTestOnly.Create );
var anonymousBar = fixture.CreateAnonymous<Bar>();
}
[Fact]
public void UsingFromFactory()
{
Fixture fixture = new Fixture();
fixture.Customize<Bar>( x=> x.FromFactory<string>( BarsForTestOnly.Create ) );
var anonymousBar = fixture.CreateAnonymous<Bar>();
}
#endif
#如果仅包含用于测试的
公开课事实
{
[事实]
公开无效事实()
{
夹具=新夹具();
fixture.Register((字符串名称)=>BarsForTestOnly.Create(名称));
var anonymousBar=fixture.CreateAnonymous();
}
[事实]
public void FactSyntax2()//只是上面事实的一个变体
{
夹具=新夹具();
fixture.Register(barsfortely.Create);
var anonymousBar=fixture.CreateAnonymous();
}
[事实]
使用FromFactory()的公共无效
{
夹具=新夹具();
fixture.Customize(x=>x.FromFactory(barsfortely.Create));
var anonymousBar=fixture.CreateAnonymous();
}
#恩迪夫
或者,要使您所拥有的一切正常工作,您可以:
[Fact]
public void UsingCtor()
{
Fixture fixture = new Fixture();
fixture.Register( ( string name )=> new Bar( name ) );
var anonymousBar = fixture.CreateAnonymous<Bar>();
}
[事实]
公共作废使用系数()
{
夹具=新夹具();
fixture.Register((字符串名称)=>新条(名称));
var anonymousBar=fixture.CreateAnonymous();
}
右侧方法是只测试被测系统的公共API。因此,InternalsVisibleTo充其量只是治疗症状,而不是疾病。你不能公开构造函数吗?@MarkSeemann:我可以,但是条
实例的所有可能值都列在静态类条
中,所以不需要创建其他值Er实例…+ 1这是最有意义的,根据你的评论,只有允许的值是由<代码> Bar < /代码> + 1所知道的,另一个在名称空间中隐藏“事物”的替代方案是考虑使用接口作为一种访问修饰符本身:@ Mark Seemann:已经阅读并重视了文章中的洞察力,但是它没有合作。请注意这里的一种技术。(显然,在这种特定的情况下,它(在显式实现的接口上只有方法)只有在你得到一个对象的实例之后才变得有价值,这是OP之后的鸡)。
[Fact]
public void UsingCtor()
{
Fixture fixture = new Fixture();
fixture.Register( ( string name )=> new Bar( name ) );
var anonymousBar = fixture.CreateAnonymous<Bar>();
}