2012-07-31 55 views
21
[TestMethod] 
public void TestMethod1() 
{ 
    var mock = new Mock<EmailService>(); 
    mock.Setup(x => x.SendEmail()).Returns(true); 
    var cus = new Customer(); 
    var result = cus.AddCustomer(mock.Object); 
    Assert.IsTrue(result); 
} 

public class Customer 
{ 
    public bool AddCustomer(EmailService emailService) 
    { 
     emailService.SendEmail(); 
     Debug.WriteLine("new customer added"); 
     return true; 
    } 
} 

public class EmailService 
{    
    public virtual bool SendEmail() 
    { 
     throw new Exception("send email failed cuz bla bla bla"); 
    } 
} 

EmailService.SendEmailメソッドは、それを模擬するために仮想でなければなりません。非仮想メソッドをモックする方法はありますか?非仮想メソッドをモックする方法は?

答えて

16

Moqでは、クラスに対して非仮想メソッドをモックできません。 Type mock Isolatorのような他のモッキングフレームワークを使用して、実際にILをアセンブリに組み込むか、またはインターフェイスをEmailServiceに置きモックします。

4

mockingに仮想メソッドを使用する代わりに、インターフェイスを使用することができます。このようにして、依存関係全体を模倣することができます。

public interface IEmailService 
{ 
    bool SendEmail(); 
    // etc... 
} 

public class EmailService : IEmailService 
{ 
    //... 
} 

今あなたがそのメソッドのいずれかを模擬できるようにするインターフェースIEmailServiceのモックを作成することができます。もちろん、EmailServiceオブジェクトを含む変数のタイプをIEmailServiceに変更する必要があります。

+0

私はこの手法を使うのがいいと思うし、インタフェースを使うことには確かに利点があると思う。しかし、非仮想メソッドを2つのオプションの間で評価している場合は、1)仮想化、2)インタフェースの一部としての使用、2の1の利点は何ですか? 2を選択しても、メソッドがバーチャルになっているのは、インターフェイスの一部になっているからです。 – zumalifeguard

7

非仮想メソッドをモックするには、低レベルのプロファイラAPIを使用する必要があります。現時点で私が利用可能な唯一の選択肢であると思う:

両方JustMockは非仮想メソッドをあざける、ライトエディションを持っている場合でも、商用のあるだけで、商用でご利用いただけますバージョン。 としては@aqwertとしてプロジェクトでは、Microsoftの研究から何かがあるコメントでPex and Moles

+5

私はあなたがMicrosoft Moles/Pex/Fakesをそのリストに追加できると思います。ボーナスとして、無料です。 – podiluska

+0

フェイクはVSのExpress版には含まれていません。 –

1

を指摘し、Typemock Isolatorを使用しているとき@Feliceは、任意のコードを追加または変更することなく、非仮想メソッドをモックすることが可能(と非常に簡単)だ書きました例えば:

[TestMethod,Isolated] 
    public void TestMethod1() 
    { 
     var mock = Isolate.Fake.Instance<EmailService>(); 
     Isolate.WhenCalled(() => mock.SendEmail()).WillReturn(true); 
     var cust = new Customer(); 
     var result = cust.AddCustomer(mock); 
     Assert.IsTrue(result); 
    } 

私が作成したテストは、作成しようとしたテストに似ています。

関連する問題