[英]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.