使用自动混合填充夹具的集合属性

时间:2014-04-10 16:00:00

标签: autofixture

我刚刚开始使用AutoFixture,而且我已经掌握了基础知识(从我可以看到的还有更多内容)但我有一个问题,我不是100%确定最佳做法是什么像这样。

我正在测试一个控制器,并且该过程的一部分是动作可以返回两个视图中的一个。

  • 如果某个类别有子项 - 显示类别列表视图
  • 如果某个类别没有子项显示产品列表视图

所以我正在考虑对该行为进行一些测试,但返回的夹具数据会有所不同。一个会返回0,另一个会更大,然后是零,所以我希望夹具可以帮助我。

我一直在寻找,也许我必须创建某种类型的自定义,但希望基本API可以帮助我。我试过这个:

var category = _fixture.Build<Category>()
    .Do(x => x.SubCategories = _fixture.CreateMany<Category>(3).ToList())
    .Create();

_fakeCategoryService
    .Setup(x => x.GetById(id))
    .Returns(category);

这个编译和测试运行(并且失败),但子类别总是有0,所以我认为我在do中调用Create Many是完全错误的(它有点看起来不对,但我仍然不确定是什么它应该替换为)。

更新:应该更好地阅读备忘单!

var category = _fixture.Build<Category>()
    .With(x => x.SubCategories, _fixture.CreateMany<Category>(3).ToList())
    .Create();

这有效,如果有更好的方法请告诉我。

3 个答案:

答案 0 :(得分:8)

是的,Build是正确的。


如果您要为 Category使用Build自定义创建算法:

var actual = fixture
    .Build<Category>()
    .With(x => x.SubCategories, 
        fixture.CreateMany<Category>().ToList())
    .Create();

Assert.NotEmpty(actual.SubCategories);

如果您要为所有 Category个实例自定义创建算法,请使用Customize

fixture.Customize<Category>(c => c
    .With(x => x.SubCategories,
        fixture.CreateMany<Category>().ToList()));

var actual = fixture.Create<Category>();

Assert.NotEmpty(actual.SubCategories);

答案 1 :(得分:6)

  

希望基本的API可以帮助我

如果您知道如何倾听,它确实对您有所帮助:) AutoFixture最初是作为测试驱动开发(TDD)的工具而构建的,而TDD则是关于反馈。本着GOOS的精神,你应该倾听你的测试。在这种情况下,它与Framework Design Guidelines

相同
  

DO NOT provide settable collection properties

不要将列表批发分配给属性,而应考虑

  • 使集合属性为只读,并让客户端调用Add
  • 将集合作为构造函数参数而不是变异属性

在后一种情况下,AutoFixture在调用构造函数时会自动提供填充的集合,尽管在这种特殊情况下,由于您有可能的递归图,因此可能需要explicitly handle it

在第一种情况下,AutoFixture不会立即执行任何操作,但具有AddManyTo扩展方法,使您可以在单个语句中填充集合:

fixture.AddManyTo(category.SubCategories);

答案 2 :(得分:1)

您可以使用自定义列表执行此存根:

var stub = _fixture.Build<Entity>().With(x=> x.field, config).CreateMany().ToList();

Documentation