How to run setup code only once in an xUnit.net test

一世执手 提交于 2019-12-03 04:35:35

Following the guidance in this xUnit discussion topic, it looks like you need to implement a constructor on the Fixture and also implement IDisposable. Here's a complete sample that behaves the way you want:

using System;
using System.Diagnostics;
using Xunit;
using Xunit.Sdk;

namespace xUnitSample
{
    public class SomeFixture : IDisposable
    {
        public SomeFixture()
        {
            Console.WriteLine("SomeFixture ctor: This should only be run once");
        }

        public void SomeMethod()
        {
            Console.WriteLine("SomeFixture::SomeMethod()");
        }

        public void Dispose()
        {
            Console.WriteLine("SomeFixture: Disposing SomeFixture");
        }
    }

    public class TestSample : IUseFixture<SomeFixture>, IDisposable
    {
        public void SetFixture(SomeFixture data)
        {
            Console.WriteLine("TestSample::SetFixture(): Calling SomeMethod");
            data.SomeMethod();
        }

        public TestSample()
        {
            Console.WriteLine("This should be run once before every test " + DateTime.Now.Ticks);
        }

        [Fact]
        public void Test1()
        {
            Console.WriteLine("This is test one.");
        }

        [Fact]
        public void Test2()
        {
            Console.WriteLine("This is test two.");
        }

        public void Dispose()
        {
            Console.WriteLine("Disposing");
        }
    }
}

When running this from the console runner, you'll see the following output:

D:\xUnit>xunit.console.clr4.exe test.dll /html foo.htm xUnit.net console test runner (64-bit .NET 4.0.30319.17929) Copyright (C) 2007-11 Microsoft Corporation.

xunit.dll: Version 1.9.1.1600 Test assembly: test.dll

SomeFixture ctor: This should only be run once

Tests complete: 2 of 2

SomeFixture: Disposing SomeFixture

2 total, 0 failed, 0 skipped, took 0.686 seconds

Then, when you crack open the test output file foo.htm, you'll see the other test output.

CodeZila

The old IUseFixture<T> interface in xUnit.net v1.x has been replaced by two new interfaces: IClassFixture<T> and ICollectionFixture<T>. In addition, the mechanism for injecting fixture values into your tests has changed from property setters to constructor arguments. Class fixtures are created once and shared amongst all tests in the same class (much like the old IUseFixture). Collection fixtures work the same way, except that the single instance is shared amongst all tests in the same test collection.

Ruben Bartelink

IUseFixture<T>.SetFixture gets called once for each test. The Fixture itself is only created once.

In other words, you shouldnt be doing anything in your SetFixture method, but you should be instead be triggering it in the Fixture constructor.

For one-time cleanup, implement an IDisposable.Dispose on the Fixture (it's not required though)

Note that it's a bad idea to be (even potentially) sharing state between tests. Best to use a TemporaryDirectoryFixture like this one.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!