English 中文(简体)
如何模拟网络服务
原标题:How to mock a web service
  • 时间:2009-10-23 18:14:36
  •  标签:

我是否必须改写我的法典,使之成为一个接口? 还是比较容易? 我正在使用Moq

最佳回答

我通常做的是,在我的网络服务上和仅仅在模拟上建立一个总结或适应者。

例如:

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
}
问题回答

撰写了一些关于单位测试和模拟的答复。 我在其他地方写道,必须询问你测试的实际是什么。 关于你的特殊情况,我希望答案是“我正在测试我的网络服务所揭露的业务逻辑”,和not。 “我正在测试我的网络服务”——有不同之处。


如果您的关切是server-side

你们不需要测试一般的网络服务。 管理系统已经这样做。 数百万人已经这样做。 测试运输层、议定书、网络服务的定义是浪费时间的。

您需要针对您的商业逻辑。 这样做的最佳途径是eparate阁下的网络服务业务逻辑。 审议以下事项:

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 ();
    }
}

* E/CN.6/2009/1。

// 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
}

管理受扶养人[与Austhentication Service”成员一样]是一个单独的问题。 然而,使您的网上浏览器simple Passs能够进入适当的基础业务班次,并从中完全删除逻辑,使你能够把“real”用户代码作为目标,而不是把你典型的网络服务执行推向来。


如果您的关切是client-side

你有一个业务构成部分:<>-em>查询<>网络服务,我同意,你不想为单位测试建立一个客户。

public partial class MyWebService :
    System.Web.Services.Protocols.SoapHttpClientProtocol 
{
    ...
    public string DoSomething () { ... }
}

public class MyClient
{
    public void CallService ()
    {
        MyWebService client = new MyWebService ();
        client.DoSomething ();
    }
}

这里,你们有依赖性的问题,即你不能考验我的信念。 电话服务,但不即时和主机。 尤其令人不安的是,如果您不拥有或担任过远程服务。 在这种情况下,是的,你应写上一个接口,再次把业务逻辑分开。

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
}

一般来说,如果一类受扶养人是非供应性服务,则适用“依赖性注射”或“控制转移”等模式的决定要由您决定,而你希望孤立和集体测试这些服务,这将为你的设计提供信息。 然而,如果一个班级的附属地跨越边界,例如数据库或网络服务,我非常建议采用上述模式。

其实,它只是老旧的接口开发。 你们可能已经看到它如何支付。

:

http://codeblog.jonskeet.uk/2007/09/07/how-does-everyone-else-mock-web-services/“rel=“nofollow noreferer”>很久以前就贴在上。 基本上使用部分班级和工作范围(无论是自动化还是手工作业,视您改变网络服务频率而定),你可以使网络服务代理班实施接口。 那么,你就可以把它当作正常的东西。

there is an easy way. for example if we have WebService class with the name DbService, first create an interface for it (ex. IService), and use this interface for mocking, then add a class to your project and put this:

public partial class DbService:IService {

}

leave class empty, because of web services are partial class we use this implementation. (previously





相关问题