bugfix> c# > 投稿

NMock3でGetDataをユニットテストするにはどうすればよいですか?

prcessA.RunとProcessA内の「結果」をモックできると便利です。

IAnotherServiceはGetData内の処理された値に依存するため、GetDataのパラメーターにできません。

何か案は?

サービス1

public class Service1 : IService1
{
    public Service1()
    {
    }
    public string GetData(int a)
    {
        // some process depends on input
        int b = a * new Random().Next();
        IAnotherService anotherService = new AnotherService(b);
        ProcessA processA = new ProcessA(anotherService);
        processA.Run();
        return processA.result;
    }
}

簡素化されたプロセスA 

public class ProcessA
{
    public string result;
    private IAnotherService anotherService;
    public ProcessA(IAnotherService anotherService)
    {
        this.anotherService = anotherService;
    }
    public void Run()
    {
        // Some other process here
        this.result = this.anotherService.Run();
    }
}

TestMethod1

[TestMethod]
public void TestMethod1()
{
    using (mockFactory.Ordered())
    {
        // Nothing to Mock
    }
    IService1 service1 = new Service1();
    string aaa = service1.GetData(1);
    Assert.AreEqual("XXX", aaa);
}

回答 1 件
  • 既に説明したように、依存サービスをモックアウトし、返されるものを設定する必要があります。

    以下のテストを行ったところ、動作します。 Moqを使用しますが、プリンシパルは同じです。

    public interface IAnotherService
     {
         string Run();
     }
    public class ProcessA
    {
        public string result;
        private readonly IAnotherService _anotherService;
        public ProcessA(IAnotherService anotherService)
        {
            this._anotherService = anotherService;
        }
        public string Run()
        {
            // Some other process here
            return _anotherService.Run();
        }   
    }
    
    

    次に、テストを実行します

    [Test]
    public void TestMethod1()
    {
       //Create a Mock
       var mockService = new Mock<IAnotherService>();
       //Set the expected result
       mockService.Setup(method => method.Run()).Returns("XXX");
       //Inject the mock
       var process = new ProcessA(mockService.Object);
       var result = process.Run();
       //Assert the result     
       Assert.AreEqual("XXX", result);
    }
    
    

    編集

    議論したように、私はあなたが必要とするものを期待して答えを編集しました。

    public interface IService1
        {
            string GetData(int a);
            int ValueForB { get; set; }
        }
    public class Service1Consumer : IService1
    {
        private readonly IAnotherService _anotherServiceImplementation;
        public Service1Consumer(IAnotherService service)
        {
            _anotherServiceImplementation = service;
        }
        public string GetData(int a)
        {
            ValueForB = a * new Random().Next();
            _anotherServiceImplementation.ValueFor = b;
            var processA = new ProcessA(_anotherServiceImplementation);
            return processA.Run();
        }
    }
    public interface IAnotherService
    {
        int ValueForB { get; set; }
    }
    public class AnotherService : IAnotherService
    {
    }
    public class ProcessA
    {
        public string result;
        private readonly IAnotherService _anotherService;
        public ProcessA(IAnotherService anotherService)
        {
            _anotherService = anotherService;
        }
        public string Run()
        {
            return "XXXX";
        }
    }
    
    

    次にテスト。

     [Test]
      public void TestMethod1()
      {
          //Create a Mock
          var mockAnotherService = new Mock<IAnotherService>();
          //Set the property value when called.
          mockAnotherService.Setup(method => method.ValueForB).Returns(10);//Test 1
          var service1Consumer = new Service1Consumer(mockAnotherService.Object);
          var result = service1Consumer.GetData();
          Assert.AreEqual("XXXX",result);
       }
    
    

    それがあなたを正しい方向に向けることを願っています。 ありがとう

あなたの答え