27

アプリケーションの統合テストを作成していますが、統合スイートのテストデータベースをセットアップする方法に関するベストプラクティスを見つけることができませんでした。私は、EntityFrameworkコードファーストを使用してASP.NETMVC4アプリケーションに取り組んでいます。

テストプロジェクトのテストが、デフォルトで自分のマシンのローカル開発データベースと通信していることを確認できます。テストを実行するたびに新しいデータベースが必要なため、これは理想的ではありません。

テストが別のインスタンスと通信するようにテストプロジェクトを設定するにはどうすればよいですか?SQL Server Compact Editionインスタンスをセットアップできると思いますが、これを構成する方法がわかりません。

4

3 に答える 3

26

@Justin と @Petro の回答に感謝します。私が思いついた解決策は、あなたが提案したテクニックの組み合わせです。以下で説明するソリューションは、テストの実行ごとに新しいデータベースを提供し、テストごとに個別のトランザクションを提供します。

テスト プロジェクトの App.config にテスト データベースの接続文字列を追加しました。

  <connectionStrings>
    <add name ="TestDatabase"
     providerName="System.Data.SqlClient"
     connectionString="Data Source=(LocalDb)\v11.0;Database=TestDatabase;Integrated Security=True"/>
  </connectionStrings>

セットアップとティアダウンを提供するために、統合テストの基本クラスを作成しました。セットアップはコンテキストをインスタンス化し、DB がまだ存在しない場合は作成し、トランザクションを開始します。Teardown はトランザクションをロールバックします。

public class EntityFrameworkIntegrationTest
{
    protected MyDbContext DbContext;

    protected TransactionScope TransactionScope;

    [TestInitialize]
    public void TestSetup()
    {
        DbContext = new MyDbContext(TestInit.TestDatabaseName);
        DbContext.Database.CreateIfNotExists();
        TransactionScope = new TransactionScope(TransactionScopeOption.RequiresNew);
    }

    [TestCleanup]
    public void TestCleanup()
    {
        TransactionScope.Dispose();
    }
}

最後に、すべてのテストの実行後にデータベースを削除するクラスがあります。

[TestClass]
public static class TestInit
{
    // Maps to connection string in App.config
    public const string TestDatabaseName = "TestDatabase";

    [AssemblyCleanup]
    public static void AssemblyCleanup()
    {
        Database.Delete(TestDatabaseName);
    }
}

Entity Framework に関するこのブログ投稿は、Entity Framework が内部で/慣習的に行っていることをより深く理解するのに役立つことがわかったことを付け加えておきます。

于 2012-12-19T11:46:05.627 に答える
7

単体テスト プロジェクトの app.config で、新しい DB インスタンスを指す接続文字列を設定するだけです。

その後、テスト クラスで初期化メソッドとクリーンアップ メソッドを使用して、DB を作成および削除できます。

接続文字列は通常のものです。

<add name="UnitTestDBConnection" connectionString="Data Source=(local);Initial Catalog=UnitTestDB;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>

次に、DB を作成するには、テストごとに 1 回、次のようにします。

    YourContext _ctx;

    [TestInitialize]
    public  void Initiaslise()
    {

        YourNameDbInitialise initialiser = new YourNameDbInitialiseForTest();
        Database.SetInitializer(initialiser);

        _ctx = new YourNameContext();

        initialiser.InitializeDatabase(_ctx);         
    }

これは各テストの最後に削除します

    [TestCleanup]
    public  void Cleanup()
    {
        Database.Delete("YourName");
    }
于 2012-12-13T09:57:02.087 に答える
5

NUnitを使用している場合は、Setup/Teardown属性withを使用TransactionScopeして、変更をデータベースにコミットしないようにすることができます。

[SetUp]
public void SetUp()
{
    transaction = new TransactionScope();
}

[TearDown]
public void TearDown()
{
    if(transaction != null) 
       transaction.Dispose();
}

他の単体テストフレームワークを使用している場合は、類似した属性が必要です。すべての統合テストフィクスチャの基本クラスDbItegrationTestを作成することをお勧めします。これにより、このクラスから派生した場合、すべてのテストメソッドがデータベースへのコミットを実行しなくなります。

他のデータベース用にEntityFrameworkを構成するには、テストアセンブリのdb接続文字列をオーバーライドしてください。

于 2012-12-13T09:59:05.867 に答える