简体   繁体   English

单元测试依赖方法

[英]Unit testing dependent methods

I would like to unit test a method on a class I have made, but this method requires another method to be called first.我想在我制作的 class 上对一个方法进行单元测试,但是这个方法需要先调用另一个方法。 Example:例子:

// This would work
MyClass myClass1 = new MyClass(mockDevice);
myClass1.Run(myDatastructure);
myClass1.Stop();

// This would throw an InvalidOperationException
MyClass myClass2 = new MyClass(mockDevice);
myClass2.Stop();

Run is starting an operation on a hardware device, and Stop is of course trying to stop that operation (sending a reset-command and starting a timeout-timer). Run是在硬件设备上启动一个操作,而Stop当然是试图停止该操作(发送一个重置命令并启动一个超时计时器)。

Anyway I would like to test various post-conditions of calling Stop , but I would like NOT to have to call Run , because I am testing Stop - not Run : I would like something like this:无论如何,我想测试调用Stop的各种后置条件,但我不想调用Run ,因为我正在测试Stop - 而不是Run :我想要这样的东西:

MyClass myClass = new MyClass(mockDevice);
myClass.Stop();
Assert.IsTrue(mockDevice.ResetCalled);

So far I only see one possible solution, and that is to create a TestableMyClass that inherits from MyClass , that makes it possible to set the right internal state of the MyClass instance before calling Stop .到目前为止,我只看到了一种可能的解决方案,那就是创建一个继承自MyClassTestableMyClass ,这样就可以在调用Stop之前设置MyClass实例的正确内部 state 。 The problem with this solution is that I have to change my MyClass -implementation to have protected members instead of private members, and I don't like the idea of having to change the implementation in order to test it!这个解决方案的问题是我必须更改我的MyClass -实现以具有受保护的成员而不是私有成员,而且我喜欢必须更改实现才能对其进行测试的想法!

Should I use this solution, is there an error in my design, or is there a smarter way of doing this?我应该使用这个解决方案,我的设计是否有错误,或者有更聪明的方法吗?

As far as I see it, you are already testing Stop in the two ways in which it can be used (with and without a running operation).据我所知,您已经在以两种可以使用它的方式(有和没有运行操作)测试Stop As long as the mockDevice is doing its job, it seem to me that you're testing it reasonably.只要mockDevice在做它的工作,在我看来你正在合理地测试它。 Ideally you should be able to verify the commands sent to the device etc (which most mock frameworks will make simple).理想情况下,您应该能够验证发送到设备等的命令(大多数模拟框架会使其变得简单)。

In this situation, personally, I would have two tests for this:在这种情况下,就个人而言,我将对此进行两项测试:

  1. Test without Run() being called first.在不首先调用 Run() 的情况下进行测试。 I would test if it really throws the exception.我会测试它是否真的抛出异常。 I would also test if the post conditions are what I expect them to be.我还将测试后置条件是否符合我的预期。
  2. Test with Run() being called first.首先调用 Run() 进行测试。 I would test only the post conditions, that I expect.我只会测试我期望的后置条件。

Those are the only two important uses of the method that have different behaviors - therefor I would test them both.这些是该方法仅有的两个具有不同行为的重要用途——因此我将对它们进行测试。

EDIT: I understand, why you don't want to call run, before stop - you think that if run fails, the test, that is supposed to only test stop method will most likely fail as well.编辑:我明白,为什么你不想在停止之前调用运行 - 你认为如果运行失败,那么应该只测试停止方法的测试很可能也会失败。

However, I would assume, that you also have test for the run method.但是,我假设您也对 run 方法进行了测试。 This means, that when the tests, that test the behavior of run method pass - stop method tests must pass as well.这意味着,当测试运行方法的行为通过时,停止方法测试也必须通过。 If the run method tests fail, then the results of run method tests are undefined - they may or may not fail.如果 run 方法测试失败,则 run 方法测试的结果是未定义的——它们可能会或可能不会失败。

So, I'd say, don't be afraid to call other dependent methods in your tests, but make sure you test those dependent methods in separate tests.所以,我想说,不要害怕在测试中调用其他依赖方法,但要确保在单独的测试中测试这些依赖方法。

It won't help your immediate problem, but I tend to favour mapping state to type rather than having objects with different modes.它不会帮助您解决眼前的问题,但我倾向于将 state 映射到类型,而不是使用具有不同模式的对象。

IdleDevice idle = new IdleDevice(mockDevice);
RunningDevice running = idle.Run(myDatastructure);
running.Stop();

// This would not compile, as IdleDevice has no Stop method
IdleDevice idle = new IdleDevice(mockDevice);
idle.Stop();

If you can't compile impossible situations, you don't need to test them.如果你不能编译不可能的情况,你就不需要测试它们。

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

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