chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hi guys,
I have a class under test that goes through various states. Certain actions can only be done to the class when the object instance is in a given state. State transitions are triggered by a Timer.

Now, I'd like to be able to speed up my tests, rather than having Thread.Sleep in the tests waiting for the object to go through the various state transitions.

Is there anyway that I can mock the Timer and "poke" it to trigger the callback (and thus state transition) from my test?

Pete
________
GYRO
asked by pmcevoy (4.7k points)

3 Answers

0 votes
Hi
If you are using the Timer class than you will run into the mscorlib problem.
TypeMock can not mock the mscorlib types. :evil:
The workaround is to create a wrapper class around the Timer class and than mock your class.
Hope it helps.
answered by ohad (35.5k points)
0 votes
Hi,
Nice question. There are several issues here.
First: What Timer are you using?
There are 3 timers in .NET

:arrow: System.Threading.Timer
As this is defined in mscorlib, there is no way to mock it.
As Ohad wrote there is a simple way to overcome this buy wrapping the Timer in you own class.

:arrow: System.Timers.Timer
There are a two ways:
1. Change the intreval to 1ms using the swap parameters:
Mock mock = MockManager.Mock(typeof (Timer), Constructor.NotMocked);
mock.ExpectSetAlways("Interval").Args(new Assign((double)1));

2. Mock the event and fire it.
Mock mock = MockManager.Mock(typeof (Timer), Constructor.NotMocked);
MockedEvent handler = mock.ExpectAddEvent("Elapsed");
//
   ...
// fire the event
handler.Fire(null, null);


:arrow: System.Windows.Forms.Timer
Same as System.Timers.Timer but the event is "Tick"
1. Change Interval
Mock mock = MockManager.Mock(typeof (Timer), Constructor.NotMocked);
mock.ExpectSetAlways("Interval").Args(new Assign((double)1));

2. Fire the Event
Mock mock = MockManager.Mock(typeof (Timer), Constructor.NotMocked);
MockedEvent handler = mock.ExpectAddEvent("Tick");
//
   ...
// fire the event
handler.Fire(null, null);
answered by scott (32k points)
0 votes
Thanks gents,
I ran into the mscorlib mocking problem and yes, I did decide to wrap the construction of the System.Threading.Timer.

So what I have done within the test, is mock the helper, and return a timer that does nothing. So within the class under test, no state transitions are made by the timer any more. I then allowed my test to _manually_ trigger a state transition through an internal method.

This approach is really so much better than I had hoped - it allows for much finer control of the object under test during different scenarios.

For safety, I have a single test which validates that when the timer is not mocked, that the state transitions are made within the time limts etc.

Cheers!
Pete
________
SILVER SURFER VAPORIZER
answered by pmcevoy (4.7k points)
...