9

i have a simple Setup method in my tests thats creates two instances of an object (make by and Id and a Description properties) and i have done it with autofixture:

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

next i try to save objects to db but i get error of duplicate key, i debug the setup and see that o1 and o2 have the same Id

According to Wiki, number should be generate progressivly:

Autogenerated Number

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

Sample Result

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

but seem id does not work in this way with object property so now i use this simple workaround:

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

but don't like it very much

is here a way to use ISpecimenBuilder for setting up Autofixture to make it generate progressive id?

Some more info:

this is my base test class:

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

and test setup:

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

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

strange things is:

if I debug of the specific test objects are created with different id and random, but if I debug of all the tests of my project (with visual studio 2013 using Nunit runner) id's are created equal

EDIT2

MyObject definition, quite complex, sorry:

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()
    {           
    }
}

EDIT 3

image of the strange things make with Nunit (I was afraid it might depend on Visual Studio),

single test run link

project test run link

gt.guybrush
  • 1,320
  • 3
  • 19
  • 48
  • Did you by any chance freeze an `int` before creating those two objects? – dcastro Aug 21 '14 at 09:30
  • can you explain it better? think – gt.guybrush Aug 21 '14 at 09:36
  • 3
    Using AutoFixture 3.20.0, I can't reproduce your issue. The Ids are not sequential, but they're not equal either. They seem to be random integers: https://dotnetfiddle.net/jnSaeZ – dcastro Aug 21 '14 at 09:37
  • Did you do something like this: `fixture.Freeze()` or `fixture.Freeze(20)`, or did you decorate any of the tests' arguments with the `[Frozen]` attribute? – dcastro Aug 21 '14 at 09:38
  • not always the case: if I debug of the specific test objects are created with different id and random, but if I debug of all the tests of my project (with visual studio 2013 using Nunit runner) id's are created equal. i never use Freeze – gt.guybrush Aug 21 '14 at 09:41
  • question edited with complete code – gt.guybrush Aug 21 '14 at 09:58
  • Can you provide the source code for `MyObject` class? – Nikos Baxevanis Aug 21 '14 at 10:14
  • done, even it's quite complex and translate now from my italian object class to english generic one – gt.guybrush Aug 21 '14 at 10:21
  • the image of error during debug test. object are with italian name but Persona is MyObject in the code above http://cubeupload.com/im/JYd8jH.jpg as tell before the error rais only when debugging all tests of my project, running a single test method or a single class works fine – gt.guybrush Aug 21 '14 at 10:31
  • i added image of test run directly with Nunit. all error you see is caused by duplicate id, all test singly works – gt.guybrush Aug 21 '14 at 10:41

1 Answers1

9

This is because in your base class property to get the Fixture, you are returning a new Fixture object every time. The auto generation of Ids can only be guaranteed per Fixture instance.

Change this:

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

to this:

public class BaseDBTest
{     
    private Fixture _fixture = new Fixture();
    public BaseDBTest()
    { }
    public Ploeh.AutoFixture.Fixture fixture { get { return _fixture; } }
}
demoncodemonkey
  • 11,730
  • 10
  • 61
  • 103