[英]Unit testing / mocking XML-RPC.net calls
我正在开发使用CookComputing XML-RPC.net的应用程序
我的问题是如何对调用外部rpc方法的方法进行单元测试。
如果我们以网站上的示例为例:
//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);
}
}
我们如何才能有效地测试IStateName的结果,而无需实际访问http://www.cookcomputing.com/xmlrpcsamples/RPC2.ashx
我想一个好的开始是在MyStateNameService
上使用MyStateNameService
的构造函数,并在IStateName上传递假的(或嘲笑的)实例。
我有兴趣测试它的实际内容-例如伪造端点的响应,并以某种方式返回,而不仅仅是验证GetStateName
调用了服务...
编辑
我不是在尝试测试服务的内容 ,而是我的班级将对此做些什么。
例如,假设响应为:
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><string>My State Name</string></value>
</param>
</params>
</methodResponse>
我想“假”该响应一些如何测试MyStateNameService.GetStateName
实际上返回了“我的州名”
您的问题出在这里应用的Singleton模式。
XmlRpcProxyGen.Create<IStateName>();
因此,使用依赖注入(按构造函数)的想法是一个好的开始。 (您是否使用IoC容器?)
接下来是为IStateName
服务创建一个Mock / Fake / Stub。 这可以通过许多方式来实现。
使用动态模拟系统可以为您节省一些工作,但是您需要了解它们的用法。
使用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.