Reputation: 8875
I've done quite a lot of reading up on the subject of testing complex classes and private methods.
The general consensus seems to be:
So, I need your help.
So I have a relatively simple class whose long running job it is to:
Aditionally:
The point of the class is to abstract a lot of the fault tolerance and threading... basically by using a simple Timer Class and some internal lists to keep track of errors etc.
Because of the Timer, certain methods are called on different threads asynchronously... additionally a bunch of the methods rely on global private fields.
How should I test this class... particularly because so many methods are private?
cheers guys
Upvotes: 3
Views: 262
Reputation: 56660
I would extract the code to poll the data into a separate class that can be mocked, and also extract the code that sends that data for the same reason. You might want to extract the data mapping code, depending on how trivial it is.
I would definitely use mock timers in the unit tests, otherwise your tests are hard to set up and slow to run. You can either pass in the timer in the constructor, or expose a property that you can set. I often create a regular timer in the constructor and then overwrite that from my unit test.
You might also be able to extract the retry logic so that it can be tested separately from the other code. Passing in a delegate of the code to try and retry might be a way to decouple the data code from the retry logic. You can also use IEnumerable
and the yield
statement to generate your data and feed it to the retry code. Essentially, I'm looking for ways to make it so that the retry code doesn't directly call the target code that it's supposed to try and retry. That makes it easier to test and generate all possible errors for, although you can get some of the same benefits by just mocking out that target code.
If you really have multithreaded scenarios that you need to test, there are some tools out there to coordinate threads from within a test. One of them is a port I created of Java MultithreadedTC called TickingTest.
Upvotes: 4
Reputation: 54316
You could try using something like JMock. This will let you replace the real Timer with a mock Timer that you can control. You can then set up test cases that fire method calls in a defined order, and you can also set up error conditions by creating a mock data source.
EDIT: Whoops! Didn't see the C# tag. Maybe there's a C# equivalent to JMock.
Upvotes: 1