Xunit multiple IClassFixtures

2019-05-06 12:26发布

My question is How to setup multiple fixtures in one test class?

But the constructor of Zoo class can not handle multiple fixtures.

For exemple:

public class Zoo : IClassFixture<Tiger>, IClassFixture<Wolf>, IClassFixure<Bird>
{
   private IFixture fixture;
   public Zoo(IFixture fixture) 
   { 
    this.fixture = fixture; 
   }

   [Fact]
   public void TestAnimal()
   {
    //Arrange 
    int actualBonesCount = this.fixture.BonesCount;
    int expectedBonesCount = 2;

    //Act & Assert
    Assert.Equal(expectedBonesCount, actualBonesCount );
   }
} 

A tiger class

public class Tiger : FixtureBase
{
   public Tiger()
   {
    this.BonesCount  = 4;
   }
}

A bird class

public class Bird: FixtureBase
{
   public Bird()
   {
    this.BonesCount  = 2;
   }
}

Test fixture base class

public class FixtureBase : IFixture
{
   public int BonesCount { get; set; }
}

And interface

public interface IFixture
{
   int BonesCount { get; set; }
}

2条回答
手持菜刀,她持情操
2楼-- · 2019-05-06 12:51

First of all, let's recall when we want to use Class Fixtures in xUnit:

When to use: when you want to create a single test context and share it among all the tests in the class, and have it cleaned up after all the tests in the class have finished.

As you've said, you'd like to reuse methods from Zoo test class to implementation tests. Since implementations use inheritance, why not use inheritance for test classes too?

public abstract class Zoo
{
    protected IFixture Fixture;

    [Fact]
    public void TestAnimal()
    {
        //Arrange 
        int actualBonesCount = Fixture.BonesCount;
        int expectedBonesCount = 2;

        //Act & Assert
        Assert.Equal(expectedBonesCount, actualBonesCount);
    }
}

public class BirdTests : Zoo, IClassFixture<Bird>
{
    public BirdTests(Bird fixture)
    {
        Fixture = fixture;
    }
}

public class TigerTests : Zoo, IClassFixture<Tiger>
{
    public BirdTests(Tiger fixture)
    {
        Fixture = fixture;
    }
}

Still, I don't really get how would you like for each test to pass as you've hardcoded BonesCount to 2 in a generic test.

查看更多
\"骚年 ilove
3楼-- · 2019-05-06 12:55

This is solution i came to after your comment. Thank you very much!

public static IEnumerable<object[]> TestCases = 
new TheoryData<Animal>{ new Bird { Eyes = 2 } };

[Theory]
[MemberData(nameof(TestCases))]
public void TestEyes(Animal email)
{
//Arrange & Act & Assert
}

;)

查看更多
登录 后发表回答