-1

おおよそ次のようなWebサービスを使用するクラスがあります。

public class MyService : IMyService
{
    private readonly IAuxilaryService1 auxilaryService1;
    private readonly IAuxilaryService2 auxilaryService2;
    private readonly IAuxilaryService3 auxilaryService3;
    private IWebService service;

    public MyService()
    {
        auxilaryService1 = new AuxilaryService1();
        auxilaryService2 = new AuxilaryService2();
        auxilaryService3 = new AuxilaryService3();
    }

    public void DoSomething(
        string Param1,
        string Param2
        )
    {
        service = new WebService(auxilaryService1, auxilaryService2, auxilaryService3); 

        var response = service.DoSomething(Param1, Param2);
        /* ... */
    }

そして、これを実行してこれをテストしようとする単体テスト:

プライベートモックwebService;

    [SetUp]
    public void SetUp()
    {
       webService = new Mock<IWebService>();
    }

    [Test]
    public void MyService_DoSomethingTest()
    {
        IMyService myService = new MyService();

        webService.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<string>()))
                       .Returns(new Response() { Status = "Foo"});


        myService.DoSomething("Param1", "Param2");

        webService.Verify(x => x.DoSomething(It.IsAny<string>(), It.IsAny<string>()));
    }

まず第一に、これは「MyService」をテストするための良い方法です。第二に、何らかの理由でインターフェイスが適切にインターセプトされないため、私のテストでは、myService内のwebServiceに偽の応答を返すように要求しますが、実際のインスタンスは引き続き呼び出され、テストはSoap例外で失敗します。Moqにはインターフェースまたは仮想メソッドが必要ですが、インターフェースMockを提供しているのに、なぜそれをインターセプトしないのですか?何か案は?

カスタムのumbracoコンターワークフロータイプをテストしていて、コンストラクターを制御できないことを追加する必要があります。変更するとプロジェクトが壊れます。

4

3 に答える 3

2

クラスをテストするには、テスト対象のクラスにモックされた依存関係を渡す必要があります。あなたの場合、すべての依存関係はハードコーディングされMyServiceています(それらはクラスでインスタンス化されます)。依存性注入を使用して依存性を提供します。

public class MyService : IMyService
{
    private readonly IAuxilaryService1 auxilaryService1;
    private readonly IAuxilaryService2 auxilaryService2;
    private readonly IAuxilaryService3 auxilaryService3;
    private IWebService service;

    // constructor injection
    public MyService(IAuxilaryService1 service1,
                     IAuxilaryService2 service2,
                     IAuxilaryService3 service3)
    {
        auxilaryService1 = service1;
        auxilaryService2 = service2;
        auxilaryService3 = service3;
    }

    // pass IWebService into method
    public void DoSomething(string Param1, string Param2, IWebService service)
    {
        this.service = service;                
        var response = service.DoSomething(Param1, Param2);
        /* ... */
    }
}

そして今、テストはどのように見えるべきか:

private IMyService myService;

[SetUp]
public void SetUp()
{
    IAuxilaryService1 service1 = new Mock<IAuxilaryService1>();
    IAuxilaryService2 service2 = new Mock<IAuxilaryService2>();
    IAuxilaryService3 service3 = new Mock<IAuxilaryService3>();
    myService = new MyService(service1.Object,
                              service2.Object,
                              service3.Object);       
}

[Test]
public void MyService_DoSomethingTest()
{
    // Arrange
    webService = new Mock<IWebService>();

    webService.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<string>()))
              .Returns(new Response() { Status = "Foo"});
    // Act
    myService.DoSomething("Param1", "Param2", webService.Object);
    // Assert
    webService.Verify(x => x.DoSomething(It.IsAny<string>(),It.IsAny<string>()));
}

DoSomethingところで、メソッド内でwebServiceをインスタンス化し、webServiceをクラスフィールドに割り当てるのは奇妙なことです。コンストラクターを介してwebServiceをクラスに渡す必要があるかもしれませんか?

于 2013-03-26T12:20:27.997 に答える
2

モックされたインスタンスをに注入することはありませんmyService。依存関係を注入するコンストラクターを作成できます。このようなもの

  public MyService(IWebService service)
  {
      this.service = service;
  }

次に、テストでこのコンストラクターを使用する必要があります。

于 2013-03-26T12:22:15.317 に答える
2

次の行のため、実装はモックインスタンスを使用していません。

service = new WebService(auxilaryService1, auxilaryService2, auxilaryService3); 

依存性注入へようこそ。このオブジェクトをモックしたい場合MyServiceは、作成するのではなく、要求する必要があります。

コードを次のようにします。

private readonly IWebService webService;

public MyService(IWebService webService)
{
  this.webService = webService;
}

public void DoSomething(...)
{
   var response = webService.DoSomething(Param1, Param2);
    /* ... */
}

また、テストでは、モックインスタンスをコンストラクターに渡す必要があります。

IMyService myService = new MyService(webService);
于 2013-03-26T12:24:38.777 に答える