2013-10-10 35 views
6

我想使用AutoFixture创建自定义对象的列表。我希望第一个N对象具有一个属性设置为一个值,其余的设置为另一个值(或仅由Fixture的默认策略设置)。如何为列表中的项目的子范围分配属性?

我知道我可以使用Fixture.CreateMany<T>.With,但是这适用于所有函数的列表成员。

NBuilder中有提供此功能的名为TheFirstTheNext(以及其他)的方法。其使用的一个例子:

提供类Foo

class Foo 
{ 
    public string Bar {get; set;} 
    public int Blub {get; set;} 
} 

一个可以实例一堆Foo就像这样:

class TestSomethingUsingFoo 
{ 
    /// ... set up etc. 

    [Test] 
    public static void TestTheFooUser() 
    { 
     var foosToSupplyToTheSUT = Builder<Foo>.CreateListOfSize(10) 
      .TheFirst(5) 
       .With(foo => foo.Bar = "Baz") 
      .TheNext(3) 
       .With(foo => foo.Bar = "Qux") 
      .All() 
       .With(foo => foo.Blub = 11) 
      .Build(); 

     /// ... perform the test on the SUT 
    } 
} 

这给出了Foo类型的对象的列表以下属性:

[Object] Foo.Bar Foo.Blub 
-------------------------------- 
0   Baz  10 
1   Baz  10 
2   Baz  10 
3   Baz  10 
4   Baz  10 
5   Qux  10 
6   Qux  10 
7   Qux  10 
8   Bar9  10 
9   Bar10  10 

(本Bar9Bar10值代表NBuilder的默认命名方案)

是否有一个‘内置’的方式来实现这一目标使用AutoFixture?或者是一种惯用的方式来建立一个像这样的行为?

+0

'Foo'类是什么样的? –

+0

@MarkSeemann我已经用'Foo'扩展了这个例子,使它更清晰一些。如果您的意思是我的真实项目中的“Foo”是代理的实际类,它就是一样的:只有一个带有gettable/settable的'string','int','DateTime'字段的POCO。 – Peter

回答

10

迄今为止做的最简单的方法是这样的:

var foos = fixture.CreateMany<Foo>(10).ToList(); 
foos.Take(5).ToList().ForEach(f => f.Bar = "Baz"); 
foos.Skip(5).Take(3).ToList().ForEach(f => f.Bar = "Qux"); 
foos.ForEach(f => f.Blub = 11); 

指定值的属性已经内置在C#,所以不是提供了一个严格的API,它不可能让你做你想做的一切,the AutoFixture philosophy is to use the language constructs already available

接下来的哲学步骤是,如果你经常需要做这样的事情,SUT可能会受益于重新设计。

+0

是的,那是我最终使用的策略。我从您的链接讨论中了解到,此用例与AutoFixture的核心意图不同。我只是习惯了NBuilder的美味句法糖...糖,我怀疑我可以在IEnumerable 的基础上实现自己,如果我真的想让我的代码“流利”的话。 – Peter

+1

整洁的解决方案。恕我直言,我仍然认为这将是很好,如果这是内置的。 – Phil

相关问题