7

当 WSDL.exe 生成 Web 服务的代理时,是否可以让 WSDL.exe 生成接口以及或代替具体类?

我们正在使用来自 ASP.Net 应用程序的第 3 方 Web 服务,并且使用 WSDL.exe 生成了我们的代理类,一切都很好。

我现在想通过伪造 Web 服务来针对我的包装器和业务类编写测试。代理没有接口或抽象基类,它们被标记为内部,这意味着如果不将我的 Fake/mock 测试代码放入我的业务项目/程序集中,我就无法从它们继承。

我可以手动创建一个界面(使用 resharper)并编辑类,但是如果第三部分更改了他们的 WSDL/web 服务,我或我的继任者也必须手动编辑界面和自动生成的类,这似乎从来都不是一个好的主意。

伪造或模拟此服务的最优雅方式是什么?我应该把假货放在商业项目中吗?我应该手动编辑文件并创建界面吗?我应该做一些完全不同的事情吗?

4

3 回答 3

7

是的,在菲利普的回答的提示下,我开始了一个,并且可能想出了一个可行的解决方案。使用 WSDL.exe,我生成了接口(使用 /si 开关)普通代理类,并将它们添加到我的业务项目中。

然后我创建了一个从具体类继承并实现接口的新类。这个小类基本上不包含任何代码,因为继承的具体成员提供了接口成员的隐式实现。代码第一次编译,我已经能够将这个小“垫片”(?适配器?)类替换到我的集成测试中,并针对实时 3rd 方服务器执行调用。

我现在可以创建实现接口的其他类(模拟或伪造),并用它们代替“shim”类。

编辑: 好的,我在这方面做了一些进一步的工作,除非有一些复杂的情况,它正在工作。

第一个重要问题是代理类仍被标记为“内部”,因此派生(适配器/垫片)类也必须是内部的。如果您将 Factory 类放入您的业务项目/程序集中,该类是新的代理类,并将它们作为接口返回,这不是问题。

我发现的第二个问题是我们显式设置了 Web 服务的 URL 和超时属性,但这些不包含在接口中,而是通过 SoapHttpClientProtocol 从 System.Web.Services.Protocols.WebClientProtocol 继承。再次,我在工厂处理了这个问题,因为我很高兴它不在接口中的实现细节。

编辑:在测试和开发我们的 Facade 时,这对我来说仍然很有效。自从在接口后面获得代理后,我还创建了一个日志装饰器类,该类捕获大量示例调用以供使用调试,以及当第 3 方服务器离线时。

我在这里更详细地写了我所做的事情:http: //www.flowerchild.org.uk/archive/2010/09/21/mocking-or-faking-or-maybe-stubbing-a-wsdl -exe-soap.html

于 2010-09-15T12:38:21.850 回答
4

您可以使用/serverinterface/si开关运行 wsdl 以获取 wsdl 中每个绑定的接口。这旨在为您提供来自 wsdl 文档的服务器端框架,但是如果我正确理解了这个问题,这些界面应该可以帮助您。

编辑——阅读评论后,我相信我误解了这个问题——你想要客户端接口/具体,这样你就可以编写合同而不是实现。/si开关可能根本不会给你你想要的东西 。

我不知道任何可以给你这种行为的开关,因为 wsdl 基本上创建了以下三件事之一:1)客户端代理类:2)服务器抽象类(用于创建服务器实现)3)服务器接口(再次,用于创建服务器实现 - 这只是 iface 而不是抽象类)我看不到任何强制客户端代理类实现接口的方法(除了数据类型上的 INotifyPropertyChanged)

于 2010-09-15T11:37:29.640 回答
1

我一直发现这些生成的类太大而无法轻松模拟(方法/属性太多)。

相反,创建一个仅实现您需要的调用的外观或存储库,并仅使用您关心的属性传回 DTO 样式对象。

针对真实的 Web 服务编写一些简单的集成测试,然后在其余测试中模拟更简单的 Facade。

这种方法的另一个好处是您有效地获得了一个反腐败层,因此对第 3 方的更改只会影响您代码的一小部分。

于 2010-09-15T19:03:37.683 回答