7

AutoFixture カスタマイズを使用して、SQL Compact DB にアクセスするリポジトリをテストしています。

テストが完了したらすぐにこのデータベースを削除していただけると非常に助かります。db はカスタマイズ コンストラクターで作成されるため、削除するのに最適な場所は dispose メソッドであると思います。

私が考えているコードは次のとおりです。

internal class ProjectRepositoryCustomization : ICustomization
{
    private readonly String _dbLocation;

    public ProjectRepositoryCustomization()
    {
        var tempDbLocation = Path.Combine(Path.GetTempPath(), "TempDbToDelete");
        if (!Directory.Exists(tempDbLocation))
        {
            Directory.CreateDirectory(tempDbLocation);
        }

        _dbLocation = Path.Combine(tempDbLocation, Guid.NewGuid().ToString("N") + ".sdf");
    }

    public void Customize(IFixture fixture)
    {   
        DataContextConfiguration.database = _dbLocation;

        var dataContextFactory = new BaseDataContextFactory();
        var projRepository = new ProjectRepository(dataContextFactory);
        fixture.Register(() => projRepository);
    }

    public void Dispose()
    {
        if (File.Exists(_dbLocation))
        {
            File.Delete(_dbLocation);
        }
    }
}

同様のことを行うことは可能ですか?

4

1 に答える 1

6

@Ruben Bartelink がコメントで指摘しているように、可能です。ただし、別のアプローチをお勧めします。その理由は次のとおりです。

オブジェクトの有効期間の管理は、通常、IoC コンテナーで実行できると期待されるものです。ただし、AutoFixture はIoC コンテナーのように見えるかもしれませんが、実際には 1 つである必要はありません

AutoFixture は、DI コンテナーと多くの類似点を共有しています。自動配線をサポートし、多くの興味深い方法でインスタンスを作成するように構成できます。ただし、焦点が異なるため、DI コンテナーよりも優れていることもあれば、そうでないこともあります。

AutoFixture の主な目標は、構成可能な境界内で匿名のテスト データを簡単に作成できるようにすることです。その API は、プログラマーがテスト データの生成方法をカスタマイズできるようにすることに重点を置いていますが、テストのコンテキスト内でのみ消費されると想定されているため、データの存続期間はカスタマイズできません。

AutoFixture は、ライフタイム管理に関しては弱いです。Fixture が複数のテスト ケースに対して存在することは決して期待されないため、 TransientおよびSingleton以外のライフスタイルをモデル化しても意味がありません。[...] DI コンテナーではないため、その必要はありません。

一方、テスト フレームワークは、テスト フィクスチャの有効期間を管理するのに非常に優れています。あなたが説明していることは通常、統合テストのコンテキスト管理の一部であるため、フィクスチャ内のすべてのテストが実行される後に実行します。

例えば:

[TestFixture]
public class WithDatabaseContext
{
    private string dbLocation;
    private BaseDataContextFactory dataContextFactory

    protected BaseDataContextFactory DataContextFactory
    {
        get { return this.dataContextFactory; }
    }

    [TestFixtureSetUp]
    public void FixtureInit()
    {
        // Initialize dbLocation
        // Initialize dataContextFactory
    }

    [TestFixtureTearDown]
    public void FixtureDispose()
    {
        // Delete file at dbLocation
    } 
}

次に、テストはコンテキストを継承し、それを使用して AutoFixture を構成できます。

[TestFixture]
public void SomeTest : WithDatabaseContext
{
    private IFixture fixture;

    [SetUp]
    public void Init()
    {
        this.fixture = new Fixture();
        this.fixture.Register(
            () => new ProjectRepository(base.DataContextFactory));
    }

    [Test]
    public void Doing_something_should_return_something_else()
    {
        // ...
    }
}

この場合、一時データベースの有効期間を管理するためにテスト フレームワークを活用することで、テストのコンテキスト内でその境界を明確に伝えることができます。私の意見では、AutoFixture のカスタマイズ内にそれを隠すと、はるかに目立たなくなり、間違いなく使いにくくなります。

于 2013-03-19T14:17:31.313 に答える