简体   繁体   English

单元测试-如何对对象进行快照?

[英]Unit testing - how to snapshot an object?

I'm writting my first unit tests in VS2012 using Moq. 我正在使用Moq在VS2012中编写我的第一个单元测试。

I need to create an object that takes in multiple input parameters (not all are passed through interfaces). 我需要创建一个接受多个输入参数的对象(并非所有输入参数都通过接口传递)。

I've minimized the code for the sake of the example. 为了示例起见,我将代码最小化了。 Here's what i'm trying to do: 这是我想做的事情:

  var mockLoopControl = new Mock<LoopControl>();
  var LoopEngine = new LoopEngine(mockLoopControl.Object);

The LoopControl object is complex, has a lot of members which are used in the LoopEngine constructor. LoopControl对象很复杂,具有很多在LoopEngine构造函数中使用的成员。

For example the LoopEngine constructor performs operations with loopControl.ContextData which is again an object with a lot of members. 例如, LoopEngine构造函数使用loopControl.ContextData执行操作, loopControl.ContextData又是一个具有很多成员的对象。

From my understanding i need to assign data to the members that are used using Mock.Setup() . 据我了解,我需要将数据分配给使用Mock.Setup()的成员。 Is it possible to take for example a snapshot of the loopControl.ContextData object at application runtime and use it afterwards in my unit tests? 例如,是否可以在应用程序运行时loopControl.ContextData对象的快照,然后在我的单元测试中使用它?

I can figure out how it's possible to write unit tests for such complex architectures. 我可以弄清楚如何为如此复杂的体系结构编写单元测试。

I hope i made myself clear :) Thanks for helping out. 我希望我能说清楚:)感谢您的帮助。

Dan

You mock it so you don't need to create that complex structure. 您可以对其进行模拟,因此无需创建该复杂结构。 If LoopEngine needs to use something from LoopControl maybe it is doing to much? 如果LoopEngine需要使用LoopControl某些功能,也许它做了很多事情? Maybe it should delegate some of its work to LoopControl or other object? 也许应该将其某些工作委托给LoopControl或其他对象? You should probably extract some other objects and do something else. 您可能应该提取其他一些对象并做其他事情。

So it seems to me like you are trying to solve wrong problem here a little bit. 因此在我看来,您似乎正在尝试解决错误的问题。

And if you want to test more functionality, you are likely doing integration testing. 而且,如果您想测试更多功能,则可能要进行集成测试。 Then you may need to have more complex object structure - right. 然后,您可能需要具有更复杂的对象结构-对。 But you don't necessarily need to use mocks then, but rather checking results in real sittuations. 但是,您不必一定要使用模拟,而要在真实的场景中检查结果。

As far as I've understood your problem, you don't want to mock hundreds of properties of LoopControl , right? 据我了解您的问题,您不想模拟LoopControl数百个属性,对吗? Looks like your unit-testing of LoopEngine is getting tricky because of tight coupling between LoopControl and LoopEngine . 似乎由于LoopControlLoopEngine之间的紧密耦合,您对LoopEngine单元测试变得棘手。 You have several options here 您在这里有几种选择

  1. Stick on with mocking (I prefer to call it substitution, just not to mess with mock/fake/stub terminology). 继续进行模拟(我更喜欢称其为替代,只是不要弄乱模拟/伪造/存根术语)。
  2. Refactor LoopEngine class constructor to accept ILoopControl and LoopControl class to implement ILoopControl. 重构LoopEngine类构造函数以接受ILoopControl和LoopControl类来实现ILoopControl。 It would ease mocking a lot. 这样会大大简化嘲笑。
  3. Refactor LoopControl other ways, 'cause loopControl.ContextData doesn't sound good for me (possible mix of model and controller or smth like this). LoopControl其他方式重构LoopControl ,因为loopControl.ContextData听起来对我不好(可能是模型和控制器的混合,或者像这样)。 By reviewing your LoopControl class and it's aims you would probably extract some other class, that holds exactly what is needed for LoopEngine initialization (higher cohension is always a plus). 通过回顾您的LoopControl类,它的目标可能是提取一些其他类,该类完全满足LoopEngine初始化的需要(更高的LoopEngine总是一个加号)。
  4. Don't bother with any refactoring and unit-testing and doing some integration testing of the LoopEngine and LoopControl pair (but any errors would require more investigation effort). 不要费心任何重构和单元测试,也LoopControlLoopEngineLoopControl对进行集成测试(但是任何错误都需要更多的调查工作)。

A common approach to handline unit tests in this way is to simply create a fake stand-in object that presents the class you are testing with the data you want it to be presented with in order to test it. 以这种方式进行手工单元测试的一种常见方法是,简单地创建一个伪造的替代对象,该对象将要测试的类与要呈现的数据一起呈现给您正在测试的类,以便对其进行测试。 Than you can isolate the class you are testing and test it using known values. 比您可以隔离要测试的类,然后使用已知值对其进行测试。

It should be relatively simple to write quick static classes that are "stand-in" for your test. 编写对您的测试“备用”的快速静态类应该相对简单。

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

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