Run code once before and after ALL tests in xUnit.net

后端 未结 8 821
野趣味
野趣味 2020-12-02 15:15

TL;DR - I\'m looking for xUnit\'s equivalent of MSTest\'s AssemblyInitialize (aka the ONE feature it has that I like).

Specifically I\'m looking for it

相关标签:
8条回答
  • 2020-12-02 15:54

    I use AssemblyFixture (NuGet).

    What it does is it provides an IAssemblyFixture<T> interface that is replacing any IClassFixture<T> where you want the object's lifetime to be as the testing assembly.

    Example:

    public class Singleton { }
    
    public class TestClass1 : IAssemblyFixture<Singleton>
    {
      readonly Singletone _Singletone;
      public TestClass1(Singleton singleton)
      {
        _Singleton = singleton;
      }
    
      [Fact]
      public void Test1()
      {
         //use singleton  
      }
    }
    
    public class TestClass2 : IAssemblyFixture<Singleton>
    {
      readonly Singletone _Singletone;
      public TestClass2(Singleton singleton)
      {
        //same singleton instance of TestClass1
        _Singleton = singleton;
      }
    
      [Fact]
      public void Test2()
      {
         //use singleton  
      }
    }
    
    0 讨论(0)
  • 2020-12-02 15:58

    As of Nov 2015 xUnit 2 is out, so there is a canonical way to share features between tests. It is documented here.

    Basically you'll need to create a class doing the fixture:

        public class DatabaseFixture : IDisposable
        {
            public DatabaseFixture()
            {
                Db = new SqlConnection("MyConnectionString");
    
                // ... initialize data in the test database ...
            }
    
            public void Dispose()
            {
                // ... clean up test data from the database ...
            }
    
            public SqlConnection Db { get; private set; }
        }
    

    A dummy class bearing the CollectionDefinition attribute. This class allows Xunit to create a test collection, and will use the given fixture for all test classes of the collection.

        [CollectionDefinition("Database collection")]
        public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
        {
            // This class has no code, and is never created. Its purpose is simply
            // to be the place to apply [CollectionDefinition] and all the
            // ICollectionFixture<> interfaces.
        }
    

    Then you need to add the collection name over all your test classes. The test classes can receive the fixture through the constructor.

        [Collection("Database collection")]
        public class DatabaseTestClass1
        {
            DatabaseFixture fixture;
    
            public DatabaseTestClass1(DatabaseFixture fixture)
            {
                this.fixture = fixture;
            }
        }
    

    It's a bit more verbose than MsTests AssemblyInitialize since you have to declare on each test class which test collection it belongs, but it's also more modulable (and with MsTests you still need to put a TestClass on your classes)

    Note: the samples have been taken from the documentation.

    0 讨论(0)
提交回复
热议问题