使用CreateMany()的AutoFixture IEnumerable <T>行为

rbe*_*amy 9 c# autofixture

这里查看帖子时,看起来我应该能够创建多个对象,使用CreateMany()它们迭代它们foreach,然后将它们作为数组返回.

我所看到的是,每次迭代似乎每次都会创建新对象.这是预期的行为吗?

要创建的实体:

public class TestEntity
{
    public int Id { get; private set; }
    public string SomeString { get; set; }
    public void SetId(int value)
    {
        this.Id = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

示例Program.cs:

private static int id;

static void Main(string[] args)
{
    var fixture = new Fixture();
    IEnumerable<TestEntity> testEntities = 
      fixture.Build<TestEntity>().CreateMany(5);

    Output(testEntities);

    foreach (var testEntity in testEntities)
    {
        testEntity.SetId(id++);
        Console.WriteLine(
          string.Format("CHANGED IN FOREACH:: hash: {0}, id: {1}, string: {2}", 
          testEntity.GetHashCode(), testEntity.Id, testEntity.SomeString));
    }

    Output(testEntities);
}

private static void Output(IEnumerable<TestEntity> testEntities)
{
    foreach (var testEntity in testEntities)
    {
        Console.WriteLine(
          string.Format("hash: {0}, id: {1}, string: {2}", 
          testEntity.GetHashCode(), testEntity.Id, testEntity.SomeString));
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这里创建了一个问题(如果这是预期的行为,可能会被删除).

编辑2011-06-02

为了获得我期望的行为,如果我不想修改AutoFixture行为,我可以使用扩展方法:

var fixture = new Fixture();
TestEntity[] testEntities = fixture.Build<TestEntity>().CreateMany(5).ToArray();
Run Code Online (Sandbox Code Playgroud)

Mar*_*ann 6

这确实是预期的默认行为.这有很多原因,但基本上可以归结为当你要求IEnumerable<T>AutoFixture时,实际上会花很多时间来确保你只得到你所要求的东西.

对许多人来说这是令人惊讶的行为.好消息是你可以改变它.

fixture.Customizations.Add(new StableFiniteSequenceRelay());
Run Code Online (Sandbox Code Playgroud)

这将改变行为,使得随后所有序列都是稳定的.您可以将该方法调用打包到自定义中以获得更好的可重用性.这可能看起来像这样(完全可选):

public class StableFiniteSequenceCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customizations.Add(new StableFiniteSequenceRelay());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 事实证明我已经写了这篇博文然后忘了它:http://blog.ploeh.dk/2011/04/18/EnumerablesAreDynamicalsoInAutoFixture.aspx (6认同)
  • 深刻的解释需要一个完整的博客文章(*将*看到未来的日子之光).简短的回答是"IEnumerable <T>"的"契约"仅指定迭代器.它与List不同.不稳定的迭代器甚至发生器也适合该接口. (2认同)
  • 是的,`yield`是实现的一部分:) (2认同)
  • 更新到上面的链接:http://blog.ploeh.dk/2011/04/18/EnumerablesaredynamicalsoinAutoFixture (2认同)