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.
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;
}
}
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);
Related
I want to unit test if an event raised by a dependency being subscribed by a class under test.
To set the context, I have the below interfaces and classes.
ITestedService.cs
public interface ITestedService
{
Task Start();
Task Stop();
}
IDependency.cs
public interface IDependency
{
event EventHandler<SoAndSoEventArgs> SomethingHappened;
Task Start();
Task Stop();
}
ISecondDependency
public interface ISecondDependency
{
Task DoYourJob(SoAndSo soAndSo);
}
TestedService.cs
public class TestedService : ITestedService
{
readonly IDependency m_dependency;
readonly ISecondDependency m_secondDependency;
public TestedService(
IDependency dependency,
ISecondDependency secondDependency)
{
m_dependency = dependency;
m_secondDependency = secondDependency;
}
public async Task Start()
{
m_dependency.SomethingHappened += OnSomethingHanppened;
await m_dependency.Start();
}
private async void OnSomethingHanppened(object sender, SoAndSoEventArgs args)
{
SoAndSo soAndSo = SoAndSoMapper.MapToDTO(args);
await m_secondDependency.DoYourJob(soAndSo),
}
}
With the above context, I want to Unit test Start() method of the TestedService class using xUnit.
I want to know how I can:
Assert if the event is attached to a handler.
Simulate the event IDependency.SomethingHappened being fired.
Verify if the OnSomethingHappened method is executed
Verify if the ISecondDependency.DoYourJob(soAndSo) is called.
From this answer, this documentation and from the guidance by #ZevSpitz in comments I was able to write the below tests for Start().
Though I couldn't verify if the same code path OnSomethingHappened got executed or was it some other subscription which calls m_secondDependencyMock.DoYourJob(soAndSo).
TestedServiceTest.cs
public class TestedServiceTest
{
readonly Mock<IDependency> m_dependencyMock;
readonly Mock<ISecondDependency> m_secondDependencyMock;
ITestedService testedService;
public TestedServiceTest()
{
m_dependencyMock = new Mock<IDependency>();
m_secondDependencyMock = new Mock<ISecondDependency>();
testedService = new TestedService(m_dependencyMock.Object, m_secondDependencyMock.Object);
}
[Fact]
public async Start_DependencyStartInvoked()
{
// Arrange
m_dependencyMock.Setup(x=> x.Start()).Verifyable();
// Act
await testedService.Start();
// Assert
//This tests if the IDependecy.Start is invoked once.
m_dependencyMock.Verify(x=>x.Start(), Times.Once);
}
[Fact]
public async Start_EventListenerAttached()
{
// Arrange
m_dependencyMock.Setup(x=> x.Start()).Verifyable();
m_dependencyMock.SetupAdd(m => m.SomethingHappened += (sender, args) => { });
// Act
await testedService.Start();
// Assert
// The below together with SetupAdd above asserts if the TestedService.Start adds a new eventlistener
// for IDependency.SomethingHappened
m_dependencyMock.VerifyAdd(
m => m.SomethingHappened += It.IsAny<EventHandler<SoAndSoEventArgs>>(),
Times.Exactly(1));
}
[Fact]
public async Start_SomthingHappenedInvoked_HandlerExecuted()
{
// Arrange
m_dependencyMock.Setup(x=> x.Start()).Verifyable();
m_secondDependencyMock.Setup(x=> x.DoYourJob(It.IsAny<SoAndSo>())).Verifyable();
// Act
await testedService.Start();
// This will fire the event SomethingHappened from m_dependencyMock.
m_dependencyMock.Raise(m => m.SomethingHappened += null, new SoAndSoEventArgs());
// Assert
// Assertion to check if the handler does its job.
m_secondDependencyMock.Verify(x=> x.DoYourJob(It.IsAny<SoAndSo>()), Times.Once);
}
}
The purpose of unit testing can be:
Verify logic results in the output you want
Verify crucial calls are made (I would only do if I want to make sure another developer does not remove a piece of code by mistake but in general verifying
whether some call is made is not necessary and even worse, makes
unnecessary maintainability work)
Having said that, you do not need to test the internals of the language. For example in this case you do not need to verify that when you register an event, that the method registered will be called. It is the job of the language to do that. That is tested by the language.
So you verified that the Start method does the calls that you expected. This by the way, as I mentioned above, only makes sense to do if there is a reason to do so such as purpose number 2 above.
Now you know the OnSomethingHappened is going to be triggered. The language guarantees that.
What you want to test is the actual implementation within OnSomethingHappened. For this, you need to make this method more testable by making it reachable (access modifier private is not going to work) and by making it's dependencies also mockable (SoAndSoMapper is not mockable).
Note: Unit testing is more of an activity of making code testable rather than the activity of figuring out how to write the test. If writing the test is difficult, that can be a sign that code is not easily testable.
public class TestedService
{
readonly IDependency m_dependency;
readonly ISomethingDoer m_somethingDoer;
public TestedService(
IDependency dependency,
ISomethingDoer somethingDoer)
{
m_dependency = dependency;
m_somethingDoer = somethingDoer;
}
public async Task Start()
{
m_dependency.SomethingHappened += m_somethingDoer.OnSomethingHanppened;
await m_dependency.Start();
}
}
interface ISomethingDoer
{
Task OnSomethingHanppened(object sender, SoAndSoEventArgs args);
}
class SomethingDoer : ISomethingDoer
{
readonly ISecondDependency m_secondDependency;
readonly ISoAndSoMapper m_soAndSoMapper;
public SomethingDoer(ISecondDependency secondDependency, ISoAndSoMapper soAndSoMapper)
{
m_secondDependency = secondDependency;
m_soAndSoMapper = soAndSoMapper;
}
public async Task OnSomethingHanppened(object sender, SoAndSoEventArgs args)
{
SoAndSo soAndSo = m_soAndSoMapper.MapToDTO(args);
await m_secondDependency.DoYourJob(soAndSo),
}
}
Now you can test what OnSomethingHappened does by creating a test class for SomethingDoer, mocking it's dependencies and verifying for example that given soAndSoMapper mock returns some value, the secondDependency is called with that value. Although once again, OnSomethingHappened doesn't do much. Therefore it is arguable whether you want to test this.
With this code:
Public class Processor {
Public Processor(Ifoo colloborator, Ibar otherCollobotator)
Public void Process() {
// if (newFoo)
// new action
If (foo)
this.colloborator.doSomething();
If (bar)
this.colloborator.doSomethingElse();
Else this.otherColloborator.doSomethingCompletelyDiffetent();
}
I want to add a another branch at the top to do something else (commented out). I know one way to do it, it involves verifying, or not, calls on colloborators using an appropriate mock/spy.
And to be clear I have done this already, succesfully and with TDD 'without' introducing another colloborator.
How would you tackle this? From a test first perspective?
I think eventually it could be refactored with something called pluggable object/adapter.
Assuming your new action also calls the collaborator, you can mock it out.
Example with RhinoMocks:
[TestMethod]
public void Test()
{
//Arrange
ICollaborator mock = MockRepository.GenerateMock<ICollaborator>();
Processor myProc = new Processor(mock, ...);
//Act
myProc.Process();
//Assert
mock.AssertWasCalled(x => x.MethodToBeCalled);
}
This will of course fail if you do not change your Process method.
Just like you said, you'd need to check that when condition is true, new action is called, and when condition is false, then new action is not called. So, first we'd define our new interface:
public interface INewAction
{
void NewAction();
}
Then, we modify our processor (note that we DID NOT yet add the new if branch):
public class Processor {
private readonly INewAction _newAction;
public Processor(Ifoo colloborator, Ibar otherCollobotator, INewAction newAction)
{
// whatever we had before
_newAction = newAction;
}
public void Process() {
if (foo)
this.colloborator.doSomething();
of (bar)
this.colloborator.doSomethingElse();
else this.otherColloborator.doSomethingCompletelyDiffetent();
}
Now we write our test cases:
[TestClass]
public class ProcessorTests
{
[TestMethod]
public void Process_GivenNewFoo_CallsNewAction()
{
// arrange 'newfoo' condition
// mockout our processor, e.g.
var mockNewAction = new Mock<INewAction>(); // this is Moq, for others use appropriate syntax, e.g. Substitute.For<INewAction>() for NSubstitute etc.
mockNewAction.Setup(x => x.NewAction()).Verifiable();
var target = new Processor(null, null, mockNewAction.Object);
target.Process();
mockNewAction.Verify(x => x.NewAction(), Times.Once);
}
[TestMethod]
public void Process_GivenNewFoo_False_DoesNotCallNewAction()
{
// arrange 'newfoo' condition to be false
// mockout our processor, e.g.
var mockNewAction = new Mock<INewAction>(); // this is Moq, for others use appropriate syntax, e.g. Substitute.For<INewAction>() for NSubstitute etc.
mockNewAction.Setup(x => x.NewAction()).Verifiable();
var target = new Processor(null, null, mockNewAction.Object);
target.Process();
mockNewAction.Verify(x => x.NewAction(), Times.Never);
}
}
When we run them, the second test will pass -> well, this is expected, because essentially the behaviour is if NOT newfoo then don't call it. But the first test WILL fails (as is the TDD approach).
And now we modify the Processor again, just the Process() method:
public void Process() {
if(newFoo)
{
_newAction.NewAction();
}
if (foo)
this.colloborator.doSomething();
of (bar)
this.colloborator.doSomethingElse();
else this.otherColloborator.doSomethingCompletelyDiffetent();
}
At this point both the tests pass and we completed the TDD cycle.
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?
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.
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)
I have code very similar to this but cannot work out how I test whether an event handler occured.
public class MyClass : MyAbstractClass
{
IFileSystem FileSystem;
public MyClass(IFileSystem myFileSys)
{
FileSystem = myFileSys;
FileSystem.EventHit += new EventHandler(FileSystem_EventHit);
}
public void FileSystem_EventHit(object sender, EventArgs e)
{
//Testing base.OnOutput is not possible which I wont go into
base.OnOutput("EventHit");
}
}
Testing code is here:
[Test]
public void DoSomething_WhenCalled_EventFired()
{
var mock = new Moq.Mock<IFileSystem>();
MyClass plugin = new MyClass (mock.Object);
mock.Object.DoSomething();
mock.Raise(x => x.EventHit += null, new EventArgs());
//Verify/Assert that MyClass handled and did something in the event handler
}
The simplest way I can think of is to just add your own handler in the test method, which should suffice I would think?
[Test]
public void DoSomething_WhenCalled_EventFired()
{
var mock = new Moq.Mock<IFileSystem>();
bool isHit = false;
mock.EventHit += (s, e) =>
{
isHit = true;
};
MyClass plugin = new MyClass (mock.Object);
mock.Object.DoSomething();
mock.Raise(x => x.EventHit += null, new EventArgs());
Assert.IsTrue(isHit);
}
As verifying something in the event handler would mean trying to test legacy code the option I went with was to test that the event fired from within the concrete type and not a mock.
[Test]
public void DoSomething_WhenCalled_EventFired()
{
FileSystem fs = new FileSystem(mock.Object, timerMock.Object);
bool WasItHit = false;
fs.EventHit += delegate { WasItHit = true; };
fs.DoSomething(); //This should call the event
Assert.IsTrue(WasItHit);
}
You need to inject a mock of whatever gets called as a result of the event handler invocation and verify it. Your comment says you can't test base base.OnOutput, but it seems to me that is exactly what you need to do.
Basically testing of a fact that method was called is not a valid test case, you should test a logic/behaviour behind a method. Obviously with a given event handler there is nothing to test, this is why a task looks not trivial.
Try out formulate in few words what are you trying to test, which test case. For instance
MyClass switches a state into the State==Hit whilst
FileSystem.EventHit event.
To do that you probably need a flag in MyClass indicating that event occured. I know, this will be just for purpose of running a test but sometimes is good to have something like that.
I have to test a method which does a certain amount of work after an interval.
while (running)
{
...
// Work
...
Thread.Sleep(Interval);
}
Interval is passed in as a parameter to the class so I can just pass in 0 or 1 but I was interested as to how to mock the system clock if this wasn't the case.
In my test I'd like to be able to simply set the time forward by TimeSpan Interval and have the thread wake up.
I've never written tests for code which acts upon the executing thread before and I'm sure there are some pitfalls to avoid - please feel free to elaborate on what approach you use.
Thanks!
If you do not wish to test the fact that the thread actually sleeps, a more straightforward approach (and one that is possible) is to have an ISleepService. You can then mock this out, and then not sleep in your tests, but have an implementation that does cause a Thread.Sleep in your production code.
ISleepService sleepService = Container.Resolve<ISleepService>();
..
while (running)
{
...
// Work
...
sleepService.Sleep(Interval);
}
Example using Moq:
public interface ISleepService
{
void Sleep(int interval);
}
[Test]
public void Test()
{
const int Interval = 1000;
Mock<ISleepService> sleepService = new Mock<ISleepService>();
sleepService.Setup(s => s.Sleep(It.IsAny<int>()));
_container.RegisterInstance(sleepService.Object);
SomeClass someClass = _container.Resolve<SomeClass>();
someClass.DoSomething(interval: Interval);
//Do some asserting.
//Optionally assert that sleep service was called
sleepService.Verify(s => s.Sleep(Interval));
}
private class SomeClass
{
private readonly ISleepService _sleepService;
public SomeClass(IUnityContainer container)
{
_sleepService = container.Resolve<ISleepService>();
}
public void DoSomething(int interval)
{
while (true)
{
_sleepService.Sleep(interval);
break;
}
}
}
Update
On a design\maintenance note, if it is painful to change the constructor of "SomeClass", or to add Dependency Injection points to the user of the class, then a service locator type pattern can help out here, e.g.:
private class SomeClass
{
private readonly ISleepService _sleepService;
public SomeClass()
{
_sleepService = ServiceLocator.Container.Resolve<ISleepService>();
}
public void DoSomething(int interval)
{
while (true)
{
_sleepService.Sleep(interval);
break;
}
}
}
You can't really mock the system clock.
If you need to be able to alter the suspend behavior of code like this, you will need to refactor it so that you are not calling Thread.Sleep() directly.
I would create a singleton service, which could be injected into the application when it's under test. The singleton service would have to include methods to allow some external caller (like a unit test) to be able to cancel a sleep operation.
Alternatively, you could use a Mutex or WaitHandle object's WaitOne() method which has a timeout parameter. This way you could trigger the mutex to cancel the "sleep" or let it timeout:
public WaitHandle CancellableSleep = new WaitHandle(); // publicly available
// in your code under test use this instead of Thread.Sleep()...
while( running ) {
// .. work ..
CancellableSleep.WaitOne( Interval ); // suspends thread for Interval timeout
}
// external code can cancel the sleep by doing:
CancellableSleep.Set(); // trigger the handle...