AutoFixture:我怎么分配的列表中的项目只有一个子范围的属性?只有一个、属性、分配、范围

2023-09-03 05:05:02 作者:情深缘浅

我想创建自定义对象的使用 AutoFixture 的列表。我想在第一 N 对象具有设置为一值的属性,而其余将它设置为其他值(或简单地由灯具的默认策略)。

I want to create a list of custom objects using AutoFixture. I want the first N objects to have a property set to one value, and the remainder to have it set to another value (or to simply be set by the Fixture's default strategy).

我知道我可以使用 Fixture.CreateMany< T>。随着,但这个应用一个函数的所有的成员列表

I am aware that I can use Fixture.CreateMany<T>.With, but this applies a function to all members of the list.

NBuilder 有命名的方法 TheFirst TheNext (等等),它提供了这种功能。其使用的一个例子:

In NBuilder there are methods named TheFirst and TheNext (among others) which provide this functionality. An example of their use:

由于一类

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

可以实例化一束就像这样的:

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 
    }
}

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

This gives a list of objects of type Foo with the following properties:

[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

(将 Bar9 Bar10 值重新present NBuilder 的默认命名方案)

(The Bar9 and Bar10 values represent NBuilder's default naming scheme)

有没有内置的方式使用,以实现这一目标 AutoFixture ?或惯用的方式来建立一个夹具这样的表现?

Is there a 'built-in' way to achieve this using AutoFixture? Or an idiomatic way to set up a fixture to behave like this?

推荐答案

目前最简单的方式做这将是这样的:

By far the easiest way to do that would be like this:

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,它不可能让你做一切你想做的事,的的AutoFixture理念是使用的语言结构已有。

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

The next philosophical step is that if you often need to do something like that, the SUT could probably benefit from a redesign.