简体   繁体   English

WCF响应对域对象的单元测试转换

[英]Unit testing translation of WCF response to domain object

From a WCF service we get a quit complex reponse with multiple nested lists and alot of properties (Up to 5 levels deep). 从WCF服务中,我们获得了一个复杂的退出响应,其中包含多个嵌套列表和许多属性(最多5级)。 This response isn't usable one on one, so we built translators that 'translate' it to a domain object we can use in our UI. 此响应不是一对一可用的,因此我们构建了将其“翻译”为可在UI中使用的域对象的转换器。

We want to unittest the translation process so we know that there are is no mismapping between fields. 我们希望对翻译过程进行单元测试,因此我们知道字段之间没有错误映射。 Currently in my unittests i'm building the response in code. 目前在我的单元测试中,我正在构建代码中的响应。 But that's quit some work, especially when i need some variants in the different responses to test the different flows. 但是这已经放弃了一些工作,特别是当我需要在不同的响应中使用一些变体来测试不同的流程时。 Also the unittests become very large files. 同样,单元测试也变得非常大。 (Only building one response can be up to more than 200 lines) (只建立一个响应可以超过200行)

I have been thinking about a way to make it easier to build up the responses and make my unittests look more clean. 我一直在想一种方法,可以更轻松地建立响应并使我的单元测试看起来更干净。

One option i have been thinking about is create for every unittest an XML file with the required response, deserialize this to the response and do my unittests on the deserialized object. 我一直在考虑的一个选项是为每个unittest创建一个带有所需响应的XML文件,将其反序列化为响应并在反序列化对象上进行单元测试。

The pro's of this method are that the unittests will become much smaller, and easier to create. 这种方法的专家是单元测试将变得更小,更容易创建。 But updating a file/element will be harder. 但是更新文件/元素将更加困难。 Or at least that's what I think. 或者至少这就是我的想法。

Anyone has some thoughts or different options for making this response building easier? 任何人都有一些想法或不同的选择,使这个响应建设更容易?

You can use a framework such as AutoFixture to help you create instances of your response. 您可以使用AutoFixture等框架来帮助您创建响应的实例。 AutoFixture will set properties automatically, thus making your constructing code really short, and you can override its behavior where needed. AutoFixture将自动设置属性,从而使您的构造代码非常短,并且您可以在需要时覆盖其行为。 Example: 例:

var mc = fixture.Build<MyResponseClass>()
   .With(x => x.SomeProperty, "SomeValue")
   .CreateAnonymous();

For non-customized values, Autofixture uses deterministic randomness to generate the values, which ensures that you get different values each time, but still keeping the values within a valid range. 对于非自定义值,Autofixture使用确定性随机性来生成值,这可确保您每次都获得不同的值,但仍将值保持在有效范围内。

When writing tests for request-response interfaces, the test cases should be written so each case tests the smallest significant part of the request where possible. 在为请求 - 响应接口编写测试时,应编写测试用例,以便每个案例尽可能测试请求中最小的重要部分。 That is to say, each test case should be testing one significant element of the request at a time. 也就是说,每个测试用例应一次测试一个重要的请求元素。

If you're following this pattern, you can should be able to identify each test case as being one of the following: 如果遵循此模式,则应该能够将每个测试用例标识为以下之一:

Core Cases 核心案例

A case that defines the "base" from which other tests are constructed. 定义从中构造其他测试的“基础”的情况。 These are always success cases which represent a successful request. 这些总是成功的案例,代表成功的请求。 You might define a core request in your unit test classes, or if you have several core cases, build the core cases from a common base. 您可以在单元测试类中定义核心请求,或者如果您有多个核心案例,则从公共基础构建核心案例。 In either case, these cases are where you're doing most of the "setting up" of values. 在任何一种情况下,这些情况都是您在大多数“设置”值的地方。

Deviation Cases 偏差案例

A case which is built off a core test case, by changing one of the pieces of information to test a different use case. 通过更改一条信息来测试不同的用例,在核心测试用例的基础上构建一个用例。 Usually these are your edge-cases and usually testing for expected failures (ie caller passing bad information). 通常这些是你的边缘情况,通常测试预期的失败(即调用者传递不良信息)。

This essentially boils down to DRY , in that your core cases are defining things which are "common" among your tests cases, so you aren't spending 200 lines setting up the values. 这基本上归结为DRY ,因为你的核心案例定义了你的测试用例中“常见”的东西,所以你不需要花费200行来设置值。 Most of your test case inputs should be expressible as "The same as <test case> but with <deviation> ", so you should write them as such. 大多数测试用例输入应该表示为“与<test case>相同但是带有<deviation> ”,因此您应该这样写。

I think what Lloyd meant is that you take your current code which is responsible for building your response objects and pack it in a separate *.dll so it is just an API or a library which you then can call from within your unit tests. 我认为Lloyd的意思是您将负责构建响应对象的当前代码带入一个单独的* .dll中,因此它只是一个API或库,您可以在单元测试中调用它。 Thus your unit tests will become much simpler. 因此,您的单元测试将变得更加简单。 Another benefit of this approach is that you could actually build two APIs: one constructing fake objects and another which queries the real service. 这种方法的另一个好处是,您实际上可以构建两个API:一个构建假对象,另一个构建查询真实服务的API。 Using an interface you could easily switch the APIs through a config setting. 使用界面,您可以通过配置设置轻松切换API。 You could also try to use a mocking framework like MoQ or smth. 您也可以尝试使用像MoQ或smth这样的模拟框架。 if it makes sense in your case. 如果它对你的情况有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM