简体   繁体   English

单元测试/模拟XML-RPC.net调用

[英]Unit testing / mocking XML-RPC.net calls

I'm developing an application that uses CookComputing XML-RPC.net 我正在开发使用CookComputing XML-RPC.net的应用程序

My question is how to unit test methods that call an external rpc method. 我的问题是如何对调用外部rpc方法的方法进行单元测试。

If we take the example on the site: 如果我们以网站上的示例为例:

//This is the XML rpc Proxy interface
[XmlRpcUrl("http://www.cookcomputing.com/xmlrpcsamples/RPC2.ashx")]
public interface IStateName : IXmlRpcProxy
{
    [XmlRpcMethod("examples.getStateName")]
    string GetStateName(int stateNumber); 
}


public class MyStateNameService 
{
    public string GetStateName(int stateNumber)
{
        IStateName proxy = XmlRpcProxyGen.Create<IStateName>();
        return proxy.GetStateName(stateNumber);
     }
}

How can we effectively test the result of IStateName without actually hitting http://www.cookcomputing.com/xmlrpcsamples/RPC2.ashx 我们如何才能有效地测试IStateName的结果,而无需实际访问http://www.cookcomputing.com/xmlrpcsamples/RPC2.ashx

I suppose a good start would be a constructor on MyStateNameService taking an IStateName, and passing in a fake (or mocked?) instance on IStateName... 我想一个好的开始是在MyStateNameService上使用MyStateNameService的构造函数,并在IStateName上传递假的(或嘲笑的)实例。

I'm interested in testing it for actual content - for example faking up the response from the endpoint, and returning that somehow, not just verifying that GetStateName calls the service... 我有兴趣测试它的实际内容-例如伪造端点的响应,并以某种方式返回,而不仅仅是验证GetStateName调用了服务...

Edit 编辑

I'm not trying to test the content of the service as such, moreover what my classes do with it. 我不是在尝试测试服务的内容 ,而是我的班级将对此做些什么。

So, for example, say the response is: 例如,假设响应为:

<?xml version="1.0"?>
<methodResponse>
  <params>
    <param>
        <value><string>My State Name</string></value>
    </param>
  </params>
</methodResponse>

I'd want to 'fake' that response some how to test that MyStateNameService.GetStateName actually returned 'My State Name' 我想“假”该响应一些如何测试MyStateNameService.GetStateName实际上返回了“我的州名”

Your problem lies in the Singleton Pattern applied here. 您的问题出在这里应用的Singleton模式。

XmlRpcProxyGen.Create<IStateName>();

So your idea with using Dependency Injection (By Constructor) is a good start. 因此,使用依赖注入(按构造函数)的想法是一个好的开始。 (Do you use an IoC container?) (您是否使用IoC容器?)

Next is to create a Mock/Fake/Stub for the IStateName service. 接下来是为IStateName服务创建一个Mock / Fake / Stub。 This can be achieved by many ways. 这可以通过许多方式来实现。

Using a dynamic mocking system may save you some work, but you need to learn their usage. 使用动态模拟系统可以为您节省一些工作,但是您需要了解它们的用法。

Classic AAA testing example for using NUnit, NSubstitute and a modified MyStateNameService : 使用NUnit,NSubstitute和修改后的MyStateNameService经典AAA测试示例:

class MyStateNameService
{
  private readonly IStateName _remoteService;
  public MyStateNameService(IStateName remoteService)
  {
    // We use ctor injection to denote the mandatory dependency on a IStateName service
    _remoteService = remoteService;
  }

  public string GetStateName(int stateNumber)
  {
    if(stateNumber < 0) throw new ArgumentException("stateNumber");
    // Do not use singletons, prefer injection of dependencies (may be IoC Container)
    //IStateName proxy = XmlRpcProxyGen.Create<IStateName>();
    return _remoteService.GetStateName(stateNumber);
  }
}

[TestFixture] class MyStateNameServiceTests
{
  [Test]
  public void SomeTesting()
  {
    // Arrange
    var mockService = Substitute.For<IStateName>();
    mockService.GetStateName(0).Returns("state1");
    mockService.GetStateName(1).Returns("state2");

    var testSubject = new MyStateNameService(mockService);


    // Act
    var result = testSubject.GetStateName(0);

    // Assert
    Assert.AreEqual("state1", result);

    // Act
    result = testSubject.GetStateName(1);

    // Assert
    Assert.AreEqual("state2", result);

    // Act/Assert
    Assert.Throws<ArgumentException>(() => testSubject.GetStateName(-1));
    mockService.DidNotReceive().GetStateName(-1);

    /* 
       MyStateNameService does not do much things to test, so this is rather trivial.
       Also different use cases of the testSubject should be their own tests ;) 
    */


  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM