views:

42

answers:

2

So basically i have a domain object and a generic repository that can do CRUD operations with that object.

public interface IBaseRepository<T> where T : BaseEntity
{
    void Add(T entity);
    void Remove(T entity);
    T ById(int id);
    IEnumerable<T> All();
}

So I have several implementations of this interface, one for each domain object.

I would like to write some integration tests (using nunit) and for that i figured i'd make a BaseRepositoryTest - like this:

public abstract class BaseRepositoryTests<T> where T : BaseEntity
{
    public abstract IBaseRepository<T> GetRepository();
    public abstract T GetTestEntity();

    [Test]
    public void AddWhenCallingAddsObjectToDatabase()
    {
        IBaseRepository<T> repository = GetRepository();
        T entity = GetTestEntity();

        repository.Add(entity);
    }
}

Now, for each domain object i would have to implement how to initialize the Repository and how to create a test entity, which seems fair, given they would be different...

All i have to do now is writing the actual test fixture right? Like this:

[TestFixture]
public class FooRepositoryTests: BaseRepositoryTests<Foo>
{
    public override IBaseRepository<Foo> GetRepository()
    {
        throw new NotImplementedException();
    }

    public override Foo GetTestEntity()
    {
        throw new NotImplementedException();
    }
}

This should get me started and give me a failed test since the throw will break it (i also tried actually implementing the methods with no luck). But the testrunners (tried both nunits GUI and resharpers test runner) just ignore my base test! It shows up and all - but reported back as Ignored.

So i did a little bit of digging... NUnit have this property on the TextFixtureAttribute that lets you specify what kind of you are testing so i tried putting the attribute

[TestFixture(typeof(Foo))]

On first the Base and also the Foo version. When put on the Foo version it still just ignores the test from the base, and when i put it on the base... well it turns red because the methods throws exceptions, which would be good except that even when i do the actual implementation in FooTests, they still won't work (obviously the Base test given the TestFixture attribute would never know what classes inherit from it, so how would it know to find the implementation).

So what am I stuck to do? I could make the test in the base test class virtual and then override it in FooBaseRepositoryTests, only to call the implementation from base, which is a lame solution i think...

What else is there to do? Am I missing something? Please help, someone... :)

A: 

I have not tried out your example but you could try if you put the attributes TestFixture and Test in the same class. Try also to put it into the base class.

schoetbi
I did try a lot of combinations of TestFixture and Test on both classes, i honestly think i tried them all ;)
Per Hornshøj-Schierbeck
A: 

When you're using the attribute [TestFixture(typeof(Foo))] on the fixture class in order to use it for different types; it's not supposed to be abstract.

If used on the Foo fixture, that class should be generic, and not typed for Foo.

From the docs:

[TestFixture]
public class AbstractFixtureBase
{
    ...
}

[TestFixture(typeof(string))]
public class DerivedFixture<T> : AbstractFixtureBase
{
    ...
}

http://www.nunit.org/index.php?p=testFixture&amp;r=2.5.5

Martin R-L
I see your point, thanks :) It doesn't solve my problem though, as the AbstractFixtureBase won't be able to have the logic for "AddWhenCallingAddsObjectToDatabase()", making me write the almost same implementation for all the derived fixtures...
Per Hornshøj-Schierbeck