我做过类似下面的事情
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
,以便能够访问内部Bar ctor然后我做了:
var fixture = new Fixture();
fixture.Register(() => new Bar(fixture.CreateAnonymous<string>()));
var foo = fixture.CreateAnonymous<Foo>();
问题:
这是使用AutoFixture的“正确”方式还是有更好的方法?
答案 0 :(得分:2)
难道你不能这样做吗?
fixture.Inject(Bars.TypeOne.SimpleBar);
这都是公开的。不需要InternalsVisibleTo,我想......
答案 1 :(得分:2)
此代码有效,因为您已经有一个引用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);
答案 2 :(得分:2)
永远不要走InternalsVisibleTo
的道路 - 不要让我开始列表,但它从你的系统的每个部分开始,包括所有测试帮助者都是强名。
如果你绝对不能(想想很久很难 - 大多数情况下,你最好放置内部,你不会考虑将你的公共api部分放入命名空间,这样它们就不会混乱 - 例如Xunit .Sdk和我用于我的雇主的各种.Internal
子命名空间,然后管理这种公开的仅仅测试的正确方法是For Tests Only的概念。注意这个名字的原因是它(正确地)被称为the xUnit Test Patterns book中的反模式。
现在,回答你的问题......
InternalsVisibleTo
公开一个只在内部(可能是DEBUG
?)软件构建的工厂(但理想情况下,你可以在另一个名称空间中使用它):
#if INCLUDE_FOR_TEST_ONLY
public static class BarsForTestOnly
{
public static Bar Create( string id )
{
return new Bar( id );
}
}
#endif
并像这样使用它:
#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
或者,要制作Just Work,您可以这样做:
[Fact]
public void UsingCtor()
{
Fixture fixture = new Fixture();
fixture.Register( ( string name )=> new Bar( name ) );
var anonymousBar = fixture.CreateAnonymous<Bar>();
}