在为Web服务生成代理时,是否可以让WSDL.exe生成接口以及代替具体类?
我们正在从ASP.Net应用程序中使用第三方Web服务,并且使用WSDL.exe生成了我们的代理类,并且很好。
我现在想通过伪造Web服务来编写针对我的包装器和业务类的测试。代理没有接口或抽象基类,它们被标记为内部,这意味着如果不将我的Fake / mock测试代码放入我的业务项目/程序集中,我就无法继承它们。
我可以手动创建一个接口(使用resharper)并编辑该类,但是如果第三部分更改了他们的WSDL / Web服务我或我的后继者还必须手动编辑接口,并自动生成类,这似乎永远不会好像是个好主意。
伪造或嘲笑此服务最优雅的方法是什么?我应该把假货放在商业项目中吗?我应该手动编辑文件并创建界面吗?我应该做一些完全不同的事情吗?
答案 0 :(得分:6)
是的,在Philip的回答的推动下,我开始了一个,并且可能已经提出了一个有效的解决方案。使用WSDL.exe我生成了接口(使用/ si开关)和普通代理类,并将它们都添加到我的业务项目中。
然后我创建了一个新类,它继承自具体类AND实现接口。这个小类基本上不包含代码,因为继承的具体成员提供了接口成员的隐式实现。代码第一次编译,我已经能够将这个小“shim”(?adapter?)类替换为我的集成测试,并对第三方服务器执行调用。我现在可以创建实现接口的其他类(模拟或伪造),并替换它们而不是“shim”类。
修改强> 好的,我已经在这方面做了一些进一步的工作,除了一些复杂的工作。
第一个重要问题是代理类仍然标记为“内部”,因此派生的(adapter / shim)类也必须是内部的。如果将Factory类放入业务项目/程序集中,而不是代理类,则将其作为接口返回,这不是问题。
我发现的第二个问题是我们明确地设置了webserice的URL和超时属性,但这些属性不包含在接口中,而是通过SoapHttpClientProtocol从System.Web.Services.Protocols.WebClientProtocol继承。我再次在工厂处理这个问题,因为它是一个我很高兴不在界面中的实现细节。
编辑: 在测试和开发我们的Facade时,这对我来说仍然很好。由于在接口后面获取代理,我还创建了一个日志装饰器类,它捕获大量示例调用以便使用调试,以及当第三方服务器脱机时。
我已经在这里写了一些更详细的内容:http://www.flowerchild.org.uk/archive/2010/09/21/mocking-or-faking-or-maybe-stubbing-a-wsdl-exe-soap.html
答案 1 :(得分:3)
您可以使用/serverinterface
或/si
开关运行wsdl,以获取wsdl中每个绑定的接口。这是为了从wsdl文档中为您提供服务器端框架,但是如果我正确理解了问题,接口应该可以帮助您解决问题。
编辑 - 在阅读评论后,我认为我误解了这个问题 - 你想要客户端界面/具体,以便你可以编写合同而不是实现。 /si
开关可能根本不会提供您想要的内容。
我不知道任何可以给你这种行为的开关,因为wsdl基本上创建了三件事之一:1)客户端代理类:2)服务器抽象类(用于创建服务器实现)3)服务器接口(再次,用于创建服务器实现 - 这只是iface而不是抽象类)我没有看到任何方法强制客户端代理类实现接口(除了数据类型的INotifyPropertyChanged)
答案 2 :(得分:1)
我总是发现这些生成的类太大而不能轻易模拟(太多的方法/属性)。
相反,创建一个仅实现所需调用的Facade或Repository,并仅使用您关注的属性传回DTO样式对象。
针对真实的Web服务编写一些简单的集成测试,然后在其余测试中模拟更简单的Facade。
此方法的另一个好处是您可以有效地获得反腐败层,因此对第三方的更改只会影响代码的一小部分区域。