永远不要走InternalsVisibleTo
- 不要让我开始列表,但它从系统的每个部分开始,包括所有测试助手都被强命名。
如果您绝对不能(仔细考虑一下-大多数情况下,最好将不考虑公共api的一部分的内部组件放入名称空间中,这样它们就不会弄乱任何东西-例如Xunit.Sdk和.Internal
我为我的雇主使用的各种子命名空间),那么管理这种东西的暴露的正确方法 For Tests Only 是For Tests Only 的概念。注意,它有一个名字的原因是它(正确地)在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
或者,要使您拥有的只是工作,您可以执行以下操作:
[Fact]
public void UsingCtor()
{
Fixture fixture = new Fixture();
fixture.Register( ( string name )=> new Bar( name ) );
var anonymousBar = fixture.CreateAnonymous<Bar>();
}