题
我必须重写我的代码做这个入口?或是有一个更简单的方法?我使用的最低采购量
解决方案
我通常做的是围绕我的Web服务构建一个包装器或适配器,然后嘲笑它。
例如:
public class ServiceAdapter: IServiceAdapter
{
public void CallSomeWebMethod()
{
var someService = new MyWebService();
someService.SomeWebMethod();
}
}
然后我只是存根服务适配器。
[Test]
public void SomeMethod_Scenario_ExpectedResult()
{
var adapterMock = new Mock<IServiceAdapter>();
//do your test
}
其他提示
已经写了几答复关于单元的测试和模拟的最近。我写的其他地方,它的重要问自己是什么 到底 你的测试。关于你的特定情况下,我希望答案是"我测试的业务逻辑我的服务是揭露", 不 "我测试我的服务"-还有一个差异。
如果你的问题是 服务器侧
你不需要测试web服务在一般。MS已经这样做的。数以百万计的人已经这样做的。测试的运输层,《议定书》的定义web服务是浪费时间。
你需要你的目标 业务逻辑.最好的方式来做到这一点是 单独的 你的业务逻辑从你服务.考虑下
public class MyWebSevice : System.Web.Services.WebService
{
private AuthenticationService _auth = new AuthenticationService ();
private int _count = 0;
[WebMethod]
public string DoSomething ()
{
// embedded business logic, bad bad bad
if (_auth.Authenticate ())
{
_count++;
}
return count.ToString ();
}
}
有没有办法来测试这一逻辑而不调用的服务。你真正想要的是
public class MyService
{
// keeners will realise this too should be injected
// as a dependency, but just cut and pasted to demonstrate
// isolation
private AuthenticationService _auth = new AuthenticationService ();
private int _count = 0;
public string DoSomething ()
{
if (_auth.Authenticate ())
{
_count++;
}
return count.ToString ();
}
}
在prod
// this web service is now a consumer of a business class,
// no embedded logic, so does not require direct testing
public class MyWebSevice : System.Web.Services.WebService
{
private readonly MyService _service = new MyService ();
[WebMethod]
public string DoSomething ()
{
_service.DoSomething ();
}
}
在测试
// test business logic without web service! yay!
[Test]
public void Test_DoSomething ()
{
MyService service = new MyService ();
string actual = service.DoSomething ();
// verify results
}
管理依赖[喜欢的AuthenticationService成员]是一个单独的问题。然而,让你WebMethods 简单passthroughs 适当的基础的企业类别和消除逻辑从他们完全可以让你的目标"真正的"用户代码,而不是管道的典型服务的执行。
如果你的问题是 客户端
你有一个企业的成分 叫 一个网络服务,并且我同意,你不想创建一个客户单元的测试。
public partial class MyWebService :
System.Web.Services.Protocols.SoapHttpClientProtocol
{
...
public string DoSomething () { ... }
}
public class MyClient
{
public void CallService ()
{
MyWebService client = new MyWebService ();
client.DoSomething ();
}
}
在这里,你必须依赖问题,即无法测试MyClient.CallService没有实例和托管你的服务.尤其令人不安,如果你不自己或东道说,远程服务。在这种情况下,是的,你应该写针对一个接口-再次单独和孤立的业务逻辑。
public interface IMyWebService
{
string DoSomething ();
}
public class MyWebServiceWrapper : IMyWebService
{
public string DoSomething ()
{
MyWebService client = new MyWebService ();
client.DoSomething ();
}
}
public class MyClient
{
private readonly IMyWebService _client = null;
public MyClient () : this (new MyWebServiceWrapper ()) { }
public MyClient (IMyWebService client)
{
_client = client;
}
public void CallService ()
{
_client.DoSomething ();
}
}
在测试
[Test]
public void Test_CallService ()
{
IMyWebService mockService = null;
// instantiate mock with expectations
MyClient client = new MyClient (mockService);
client.CallService ();
// verify results
}
在一般情况下,如果一类的依赖在内的服务,决定申请一样的图案的依赖注射[二]或控制反转[IoC]是你和你的的愿望,以孤立和单元的测试这些服务将提前通知你的设计。然而,如果一类的依赖关系 跨越边界的过程, 例如数据库或网络服务,我强烈推荐采用这些模式作为我们做以上。
真的,这只是普通的老式接口的发展。你可能已经看看它是如何付清。
:)
我发表了关于此的博文很久以前。基本上使用部分类和一些努力(自动或手动,取决于您将更改Web服务的频率),您可以使Web服务代理类实现一个接口。然后你可以正常模拟它。
有一种简单的方法。 例如,如果我们的WebService类名为DbService, 首先为它创建一个接口(例如IService),然后使用这个接口进行模拟,然后在项目中添加一个类并放入:
public partial class DbService:IService {
}
将类留空,因为Web服务是部分类我们使用此实现。 (以前