【问题标题】:How to tell Autofixture to create objects with different ID?如何告诉 Autofixture 创建具有不同 ID 的对象?
【发布时间】:2014-08-21 09:25:05
【问题描述】:

我的测试中有一个简单的 Setup 方法,它创建了一个对象的两个实例(make by 和 Id 和一个 Description 属性),我已经使用 autofixture 完成了它:

MyObject o1 = fixture.Create<MyObject>();
MyObject o2 = fixture.Create<MyObject>();

接下来我尝试将对象保存到 db 但出现重复键错误,我调试设置并看到 o1 和 o2 具有相同的 Id

根据Wiki,数字应该是逐步生成的:

Autogenerated Number

int autoGeneratedNumber = fixture.Create<int>();

Sample Result

int: 1, followed by 2, then by 3, etc.

但似乎 id 不适用于对象属性,所以现在我使用这个简单的解决方法:

MyObject o1= fixture.Build<MyObject>().With(x => x.Id, 1).Create();
MyObject o2= fixture.Build<MyObject>().With(x => x.Id, 2).Create();

但不是很喜欢

这里有没有一种方法可以使用ISpecimenBuilder 来设置 Autofixture 以使其生成渐进式 id?

更多信息:

这是我的基础测试类:

public class BaseDBTest
{       
    public BaseDBTest()
    { }
    public Ploeh.AutoFixture.Fixture fixture { get { return new Fixture(); } }
}

和测试设置:

[TestFixture]
public class MyObjectTests : BaseDBTest
{
    MyObject o1;
    MyObject o2;

    [TestFixtureSetUp]
    public void CreaDati()
    {
        o1= fixture.Create<MyObject >();
        o2= fixture.Create<MyObject >();
    }
}

奇怪的是:

如果我调试的特定测试对象是使用不同的 id 和随机创建的,但是如果我调试我的项目的所有测试(使用 Visual Studio 2013 使用 Nunit 运行器),则创建的 id 相同

EDIT2

MyObject 定义,相当复杂,抱歉:

public class MyObject: LookUpObject<MyObject, int>
{
}

public abstract class LookUpObject<TObject, TKeyType> : EquatableObject<TObject>,     IKeyedEntity<TKeyType>
    where TObject : class
    where TKeyType : struct
{
    private TKeyType id;
    private string description;
    private bool isValid;

    public virtual TKeyType Id
    {
        get { return id; }
        set { id = value; }
    }

    public virtual string Description
    {
        get { return description; }
        set { description= value; }
    }
    public virtual bool IsValid
    {
        get { return isValid; }
        set { isValid= value; }
    }

    protected LookUpObject()
    {           
    }
}

编辑 3

用 Nunit 制作的奇怪东西的图像(我担心它可能依赖于 Visual Studio),

单次测试运行link

项目试运行link

【问题讨论】:

  • 在创建这两个对象之前,您是否有机会冻结了 int?
  • 你能解释清楚吗?认为
  • 使用 AutoFixture 3.20.0,我无法重现您的问题。 Id 不是连续的,但它们也不相等。它们似乎是随机整数:dotnetfiddle.net/jnSaeZ
  • 您是否做过这样的事情:fixture.Freeze&lt;int&gt;() 或 fixture.Freeze(20),或者您是否使用 [Frozen] 属性装饰了任何测试的参数?
  • 并非总是如此:如果我调试特定的测试对象是使用不同的 id 和随机创建的,但是如果我调试我的项目的所有测试(使用 Visual Studio 2013 使用 Nunit runner)id生而平等。我从不使用冻结

标签: c# unit-testing autofixture


【解决方案1】:

这是因为在您获取 Fixture 的基类属性中,您每次都返回一个新的 Fixture 对象。只能保证每个 Fixture 实例的 ID 自动生成。

改变这个:

public class BaseDBTest
{       
    public BaseDBTest()
    { }
    public Ploeh.AutoFixture.Fixture fixture { get { return new Fixture(); } }
}

到这里:

public class BaseDBTest
{     
    private Fixture _fixture = new Fixture();
    public BaseDBTest()
    { }
    public Ploeh.AutoFixture.Fixture fixture { get { return _fixture; } }
}

【讨论】:

  • 太棒了,事实上,用“new”返回实在是太愚蠢了 :) 我过于关注单个测试(有两个调用)有效的事实
  • 你不会是第一个或最后一个做出这种假设的人;)
猜你喜欢
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-16
相关资源
最近更新 更多