38
[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メソッドが仮想でなければなりません。非仮想メソッドをモックする方法はありますか?

4

8 に答える 8

27

Moq は、クラスの非仮想メソッドをモックできません。実際にILをアセンブリに織り込むタイプモックアイソレーターなどの他のモックフレームワークを使用するか、インターフェイスを配置してEmailServiceそれをモックします。

于 2012-07-31T10:33:47.010 に答える
8

非仮想メソッドのモックには、低レベルのプロファイラー API の使用が含まれます。現時点では、利用可能な唯一のオプションは次のとおりだと思います。

JustMock にライト エディションがあっても、非仮想メソッドのモックは商用バージョンだけで利用できます。コメントで指摘されているように、プロジェクトPex and Molesには、Microsoft の研究からの何かがあります。

于 2012-07-31T10:37:41.120 に答える
6

モックに仮想メソッドを使用する代わりに、インターフェイスを使用できます。このようにして、依存関係全体をモックアウトできます。

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

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

これで、インターフェイスのモックを作成してIEmailService、そのメソッドをモックできるようになりました。もちろん、EmailServiceオブジェクトを含む変数の型をIEmailService適切な場所に変更する必要があります。

于 2012-07-31T10:35:50.110 に答える
1

@aqwert と @Felice がTypemock Isolatorを使用するときに書いたように、コードを追加または変更せずに非仮想メソッドをモックすることが可能です (そして非常に簡単です)。次に例を示します。

[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);
    }

ご覧のとおり、私が作成したテストは、作成しようとしたテストと似ています。

于 2016-11-03T16:29:37.333 に答える