2015-10-15 3 views
6

私はIDisposable DbContextを持っている仕事をしています。私はデータベースにぶつかることなくこの仕事をユニットテストしたいと思います。どのようなオプションが必要ですか?UnityでIDisposableリポジトリを扱うには?

マイクロソフトのデフォルトのFakeアセンブリを使用しています。

私の仕事:私はテストしようとしているし、それが実際にリポジトリクラスの新しいインスタンスを作成するためのテストのこの部分では、それが失敗した

public void Work() 
{ 
    do 
    { 
     //code here     
     using (var repository = new Repository<User>()) 
     { 
      repository.Save(user); 
     } 

    } while (true); 
} 

私のテスト方法:

using (ShimsContext.Create()) 
{ 
    Data.Repository.Fakes.ShimRepository<Domain.Fakes.ShimUser>.Constructor = (a) => { }; 

    Data.Repository.Fakes.ShimRepository<Domain.Fakes.ShimUser>.AllInstances.SaveT0 = (a, b) => 
    { 
    }; 

    var service = GetService(); 
    service.Work(); //Throws exception 
} 

どのように私は偽物このSave方法?

+1

参照依存性注入 - 渡されたパラメータをWork()に許可する必要があります。または、少なくともそれ以外の場合は常に実際のものを作成します。 –

+0

私はFakesに慣れていませんが、あなたのニーズに十分に対応しているとは限りません。私はこれがMoq(https://github.com/Moq/moq4)のような図書館では些細なことだと知っています。 –

+0

仕事でリポジトリの実際の具体的なインスタンスをインスタンス化しているので、Moqでもそれは自明ではありません。 –

答えて

7

ここではDIPに違反したため、ユニットテストのサービスがはるかに難しくなりました。また、一般的なリポジトリを避けて、role interfacesを好むべきです。

代わりに、リポジトリのサービスに抽象化を挿入します。 Saveメソッドを定義するIUsersRepositoryサービスの単体テストでは、単にIUsersRepositoryのスタブ実装を使用できます。

+0

はい、オブジェクトの処分はどうですか?私はそれを一度注入すると、仕事は文脈の最初のインスタンスで永遠に実行されます。 – gog

+0

Disposingは、抽象化のEntity Framework実装の実装の詳細です。従って、廃棄は、例えば、 EntityFrameworkUsersRepository。 – devdigital

2

偽物は、あなたが代わりにそれらを渡すのクラス内部の依存関係を作成しているので、あなたのコードが正しくSOLIDでDを、次のされていないことを明らかにする傾向がある。

はるかに優れたパターンでしょう順番にISaveRepositoryインターフェイスを作成します公開されたSave()メソッドを持つIDisposableを実装します。次に、リポジトリのインスタンスをクラスに挿入する必要があります。これにより、usingステートメントテストを満たし、データベースにヒットしない.Save()メソッドを定義するモックを実装することができます。

public class Test 
{ 
    private readonly ISaveRepository _userRepository; 

    public Test(ISaveRepository userRepository) 
    { 
     _userRepository = userRepository; 
    } 

    public void Work() 
    { 
     using (_userRepository) 
     { 
      var cont = true; 
      do 
      {    
       _userRepository.Save(new User()); 
       cont = false; 
      } while (cont); 
     } 
    } 
} 

public interface ISaveRepository : IDisposable 
{ 
    void Save<T>(T model); 
} 

public class Repository<T> : ISaveRepository 
{ 
    public void Dispose() { } 
    public void Save<TT>(TT model) {} 
} 

public class User {} 
+0

多くの実装でどのように処理する必要はありませんか? – gog

+0

スタブの実装には処分が必要ですか? XMLリポジトリには処分が必要ですか? Webサービスコールリポジトリには処分が必要ですか? – devdigital

+0

@gguiあなたは当初、接続を長期間保持しないように接続を再作成していたと仮定していますか? –

関連する問題