Reputation: 2834
I'm attempting to create a WPF MVVM View Model that has a dependency injected System.Timing.Timer
, and wish to test the view model with Moq.
I wrote a thin wrapper around the Timer
class that has a interface ITimer
, but am unsure of the best way to really test the timer's contribution to the class. Is there a good way to 'force' a mock elapsed event? Does somebody else have a better technique?
Upvotes: 8
Views: 3383
Reputation: 2827
You could use a framework like Moq
to trigger the event. You could also create a FakeTimer
like so:
public class FakeTimer : IMyTimer
{
private event ElapsedEventHandler elaspedHandler;
private bool _enabled;
public void Dispose() => throw new NotImplementedException();
public FakeTimer(ElapsedEventHandler elapsedHandlerWhenTimeFinished, bool startImmediately)
{
this.elaspedHandler = elapsedHandlerWhenTimeFinished;
_enabled = startImmediately;
}
public void Start() => _enabled = true;
public void Stop() => _enabled = false;
public void Reset() => _enabled = true;
internal void TimeElapsed()
{
if (this._enabled)
elaspedHandler.Invoke(this, new EventArgs() as ElapsedEventArgs);
}
}
Where TimeElapsed()
is what you would call in your unit tests to indicate that the time has passed.
It will then call off to the event associated with it.
In this example below, MyCallBackMethod
would be called on fakeTimer.TimeElapsed()
var fakeTimer = new FakeTimer(350, MyCallBackMethod, false)
Upvotes: 0
Reputation: 236208
You should test your code in isolation. Otherwise you don't know whether your code behaves as expected, or there is some side-effect in external dependency. Thus creating mockable wrappers for external resources (configuration files, timers, etc) is the only way you can separate your SUT from external code.
Upvotes: 3