I would like to unit test a method on a class I have made, but this method requires another method to be called first. 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).
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:
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
. 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!
Should I use this solution, is there an error in my design, or is there a smarter way of doing this?
Unit tests should not affect each other. Unit tests should be deterministic. Unit tests should not depend on any external state.
Unit tests can be performed manually or automated. Those employing a manual method may have an instinctual document made detailing each step in the process; however, automated testing is the more common method to unit tests. Automated approaches commonly use a testing framework to develop test cases.
Dependency injection allows unit testing, but it also allow modification of an object's behavior without altering the code of that object (open/closed principle). So, it isn't just testable code, but flexible code that results.
There are 2 types of Unit Testing: Manual, and Automated.
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). As long as the mockDevice
is doing its job, it seem to me that you're testing it reasonably. 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:
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. 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With