Reputation: 53
I have a DispatcherTimer and I check for the busy/free status of a component in the timer tick of this timer. I have to wait till the component becomes free, something like IsBusy() method returns false, and then I have to automatically start something. I want to test the scenario by first simulating the component to be busy and then make it free after some time and see that the automatic function starts. Of course, once I invoke the code under test, I enter a wait. Is it possible to set fresh expectations from test and send an update to the production code so that I can do what I need to do? I am using Nunit for unit tests.
Upvotes: 2
Views: 720
Reputation: 192216
You can use the Rhino Mocks' Do() Handler
to simulate a pre-specified wait time in the IsBusy()
method of the component being mocked:
[TestFixture]
public class TestClass
{
[Test]
public void MyTest()
{
var mocks = new MockRepository();
var mockComponent = mocks.DynamicMock<MyComponent>();
using (mocks.Record ())
{
Expect.Call(() => mockComponent.IsBusy())
.Do((Func<bool>)(() =>
{
System.Threading.Thread.Sleep(10000); // wait 10 seconds
return false;
}));
// perhaps define other expectations or asserts here...
}
using (mocks.Playback())
{
var classUnderTest = new ClassUnderTest(mockComponent);
classUnderTest.MethodUnderTest();
}
mocks.VerifyAll();
}
}
You can then test different Sleep times as needed via multiple unit tests or using NUnit's Parameterized Tests (I just arbitrarily chose to wait 10 seconds).
The ClassUnderTest.MethodUnderTest()
should be calling MyComponent.IsBusy()
at some point in its implementation either directly or perhaps indirectly via the Tick
event handler of the DispatcherTimer
you mentioned. Without seeing your code, my guess is that you might have something similar to this:
public class ClassUnderTest
{
private MyComponent myComponent;
public ClassUnderTest(MyComponent myComponent)
{
this.myComponent = myComponent;
}
public void MethodUnderTest()
{
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0,0,1);
dispatcherTimer.Start();
// ...
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
if(!myComponent.IsBusy())
{
// do something else now...
}
}
}
public class MyComponent
{
public virtual bool IsBusy()
{
// some implementation that will be faked via the Do Handler
return false;
}
}
Upvotes: 1
Reputation: 59111
Your expectations can be dynamically created, but they should be set up in one place, rather than "interactively". You shouldn't try to change them while in the middle of exercising your code-under-test.
To accomplish your goal, you could try using the Repeat
option to allow the check to loop a certain number of times:
mock.Expect(theMock => theMock.IsBusy())
.Return(true)
.Repeat.Times(5);
mock.Expect(theMock => theMock.IsBusy())
.Return(false);
Upvotes: 0