3

我做了类似以下的事情

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 的“正确”方式还是有更好的方式?

4

3 回答 3

2

你不能做这样的事情吗?

fixture.Inject(Bars.TypeOne.SimpleBar);

这都是公开的。不需要 InternalsVisibleTo,我认为...

于 2012-04-25T20:04:25.033 回答
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);
于 2012-04-26T00:28:05.297 回答
2

永远不要走InternalsVisibleTo- 不要让我开始列表,但它从系统的每个部分开始,包括所有测试助手都被强命名。

如果您绝对不能(仔细考虑一下-大多数情况下,最好将不考虑公共api的一部分的内部组件放入名称空间中,这样它们就不会弄乱任何东西-例如Xunit.Sdk和.Internal我为我的雇主使用的各种子命名空间),那么管理这种东西的暴露的正确方法 For Tests Only 是For Tests Only 的概念。注意,它有一个名字的原因是它(正确地)在xUnit Test Patterns book中被称为反模式。


现在,回答你的问题...

  1. 考虑在单独的命名空间中隐藏用户通常不需要的内容
  2. 永远不要使用InternalsVisibleTo
  3. 不要使用仅测试代码

公开一个只在内部公开的工厂(也许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>();
}
于 2012-04-26T07:53:21.490 回答