起订量 - 如何模拟Web服务调用?(Moq - How to mock web service c

2019-09-22 00:13发布

using下面打,我不想竟然打的外部资源。 我想测试someResult和使用它的代码,但每次我跑我的单元测试时,该代码仍然试图打真正的Web服务。 如何使用起订量来真伪调用Web服务,但在使用中不会嘲笑代码的其余部分?

public IMyInterface.SomeMethod()
{    
     // hits a web service
     using ( mySoapClient client = new mySoapClient() )
     {
          var someResult = client.DoSomething();
       ...
       ...
     }
}


[TestMethod()]
public void SomeMethodTest()
{
    IMyInterface target = new MyInterface();
    target.SomeMethod();

    // Assert....
}

Answer 1:

你需要去耦从消费者的Web服务实现

public class ClassIWantToTest
{
      public ClassIWantToTest(IServiceIWantToCall service) {}

      public void SomeMethod()
      {
           var results = service.DoSomething();
           //Rest of the logic here
      }
}

现在你可以使用最小起订量嘲笑IServiceIWantToCall为了测试逻辑SomeMethod



Answer 2:

为了增加泡菜的回答,我创建了一个interface一个名为我目前的服务电话IService 。 然后我创建了一个ServiceMock继承的接口类,并添加一个全局变量命名_service 。 在构造函数中我实例模拟服务,并设置了所有的接口这样的方法:

public class ServiceMock : IService
{
    Mock<IService> _serviceMock;

    public ServiceMock()
    {
        _serviceMock = new Mock<IService>();

        _serviceMock.Setup(x => x.GetString()).Returns("Default String");

        SomeClass someClass = new SomeClass();
        someClass.Property1= "Default";
        someClass.Property2= Guid.NewGuid().ToString();

        _serviceMock.Setup(x => x.GetSomeClass()).Returns(someClass);
    }

    public string GetString()
    {
        return _serviceMock.Object.GetString();
    }

    public License GetSomeClass()
    {
        return _serviceMock.Object.GetSomeClass();
    }
}

然后,注入这个类到你的代码,而不是实际的Web服务。 它会回报你将它设置为返回值。 您现在可以测试不依赖于Web服务。



Answer 3:

你首先必须能够注入的Web服务。 创建内部的someMethod一个新的()“紧密耦合”的方法来生产的代码; 你不能动态地告诉它创建一个比其他mySoapClient东西。

既然你要创建和销毁它们,我可能会建议你的代码要测试接受Func<IMySoapClient>作为方法参数或构造函数的参数。 这将是这个样子:

public IMyInterface.SomeMethod(Func<IMySoapClient> clientFactory)
{    
     // hits a web service
     using ( mySoapClient client = clientFactory() )
     {
          var someResult = client.DoSomething();
       ...
       ...
     }
}

... 要么:

public class MyClass:IMyInterface
{
   private Func<IMySoapClient> MySoapClientFactoryMethod;

   public MyClass(Func<IMySoapClient> clientFactoryMethod)
   {
      MySoapClientFactoryMethod = clientFactoryMethod;
   }

   ...

   public IMyInterface.SomeMethod()
   {    
        // hits a web service
        using ( mySoapClient client = MySoapClientFactoryMethod() )
        {
             var someResult = client.DoSomething();
          ...
          ...
        }
   }
}

现在,当你创建你想测试对象,定义生成SOAP服务,其中有你离真正的客户期望没有副作用的行为的适当的起订量模拟功能(包括能够告诉客户端的代码的Dispose()d),并通过该功能到您正在测试的类或方法。 在生产中,可以简单地定义的功能()=>new mySoapClient()或者你可以设置IoC框架和寄存器mySoapClient作为IMySoapClient,然后也寄存器MyClass的; 大多数IoC框架有足够的智慧看到的委托作为参数,并产生注入注册依赖的方法。



文章来源: Moq - How to mock web service call?