Mocking a C# timer with Moq - c#

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)

Related

How to unit test C# events with xUnit

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.

How to use moq to test code that calls protected helpers

I currently run tests that look like the following:
// In Blah.cs
public class ClassUnderTest
{
public bool MethodUnderTest()
{
// Do a bunch of stuff...
return HelperMethod();
}
protected virtual bool HelperMethod()
{
bool success = false;
// Proprietary Hardware Access.
// Database Calls.
// File System Modifications.
return success;
}
}
// In TestBlah.cs
public class TestStub : ClassUnderTest
{
public bool HelperMethodReturnValue;
protected override bool HelperMethod()
{
return HelperMethodReturnValue;
}
}
[TestClass]
public class TestingClass
{
[TestMethod]
public void ClassUnderTest_MethodUnderTest_TestHelperReturnsTrue()
{
var stub = new TestStub();
stub.HelperMethodReturnValue = true;
Assert.IsTrue(stub.MethodUnderTest());
}
[TestMethod]
public void ClassUnderTest_MethodUnderTest_TestHelperReturnsFalse()
{
var stub = new TestStub();
stub.HelperMethodReturnValue = false;
Assert.IsFalse(stub.MethodUnderTest());
}
}
The above looks fine for simple things, however the stub class gets exponentially bigger and more complex quickly.
I'd like to replace the stub class using Moq. However this won't compile because for some reason I can't set a return value on a protected method.
[TestMethod]
public void ClassUnderTest_MethodUnderTest_TestHelperReturnsFalse()
{
var mockClass = new Mock<ClassUnderTest>();
mockClass.Protected().Setup("HelperMethod").Returns(false);
Assert.IsFalse(mockClass.Object.MethodUnderTest());
}
Anyone know how I'd go about doing this? Can I do this with moq?
Looking at the moq source code I'd guess you need to explicitly call the generic version of Setup. The non-generic version seems to be used for void methods. So try
mockClass.Protected().Setup<bool>("HelperMethod").Returns(false);
Beside this, I'd recommend re-thinking your class design. If HelperMethod() is doing such a bunch of things it would be worth its own class that is injected as a dependency into ClassUnderTest. Testing a mock object, instead of using a mock object to test something "real", is not what mocking frameworks are made for (not in the first place, at least).
Protected methods are not a great way of isolating dependencies, but it does sometimes come up, particularly when adapting legacy code for testability. One option that avoids the awkward string-based Moq syntax is to make the method 'protected internal' (or just 'internal' if you don't intend to override it in normal usage from other assemblies.) You then use InternalsVisibleTo on the assembly to expose the method. This is a bit of a hack, but using a protected method for this purpose is already a bit of a hack. In some ways I prefer the 'internal' approach, as it makes it clear that this is a backdoor method that you're not supposed to use (except for testing), as opposed to a protected method that you might expect to override in normal usage.

Changing expectations on rhino mocks in a single method call

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);

How to mock events with internal constructors

I have a service responsible for subscribing to EWS for new mail notification. I've created an interface for the service in order to mock it and test a dummy implementation. However, I'm running into a wall whenever I try to manually tell what my events are supposed to do.
Here is my concrete implementation.
public interface IExchangeService
{
void Subscribe();
}
public class ExchangeServiceSubscriber : IExchangeService
{
private readonly ExchangeService _exchangeService;
private readonly IConsumer<IEmail> _consumer;
public ExchangeServiceSubscriber(
ExchangeService exchangeService,
IConsumer<IEmail> consumer)
{
_exchangeService = exchangeService;
_consumer = consumer;
}
public void Subscribe()
{
// code to subscribe
streamingConnection.OnNotificationEvent += OnEvent;
streamingConnection.Open();
}
public void OnEvent(object sender, NotificationEventArgs args)
{
foreach (NotificationEvent triggeredEvent in args.Events)
{
if (triggeredEvent is ItemEvent)
{
var propertySet = new PropertySet(ItemSchema.UniqueBody, ItemSchema.Attachments)
{
RequestedBodyType = BodyType.Text
};
EmailMessage email = EmailMessage.Bind(args.Subscription.Service,
((ItemEvent)triggeredEvent).ItemId, propertySet);
_consumer.Consume(new ExchangeEmail { Body = email.UniqueBody });
}
}
}
}
And unfortunatly, almost every class in EWS is either sealed or has an internal constructor which really limits how I decouple them, it seems. I've attempted to set the expectation for NotificationEventArgs (for example) but it uses an internal constructor.
Here is some ideas I've been fiddling with. You can read about mocking events here.
mock.Setup(x => x.OnEvent(new object(), new NotificationEventArgs()));
Issue with that is NotificationEventArgs uses an internal constructor.
I could see getting this working with some sort of wrapper but I'm not exactly sure what it would look like. One of the big problems is the way EWS is made pretty much prevents anyone from manually injecting dependencies. I'm essentially trying to test that whenever event OnEvent fires that the email will actually get consumed. Also, while I would like to test this functionality I'm not sure it's worth fighting EWS every step of the way.
Let's first see, what you can't do:
You can't subclass NotificationEventArgs because the ctor is internal.
You can't create an instance directly for the same reason.
So basically, you can't create an instance of this class using the "normal way". I assume you already checked for a factory method or class?
This leaves us with only one option: Instantiate the class using reflection, e.g. with the help of the Activator.CreateInstance method: Unit testing exception handling for third party exceptions with internal constructors, like so:
mock.Setup(x => x.OnEvent(new object(),
Activator.CreateInstance(typeof(NotificationEventArgs),
BindingFlags.NonPublic | BindingFlags.Instance,
null,
null,
null))
);

TDD can force the creation of "fake" dependencies

I'm using a boilerplate implementation of Model-View-Presenter in an ASP.NET WebForms application. My View has two events of consequence, one that signals that the user has filled out enough fields on the domain model to initiate a duplication check, and the other is a regular Save event. My pseudo code looks like this:
public class ItemNewPresenter : PresenterBase<IItemNewView>
{
public IItemService Service { get; private set; }
public IItemNewView View { get; private set; }
public ItemNewPresenter(IItemService service, IItemNewView view)
{
Service = service;
View = view;
View.OnSave += DoItemSave;
View.OnItemIsDuplicateCheck+= DoItemIsDuplicateCheck;
}
private void DoItemIsDuplicateCheck(object sender, CheckItemDuplicateEventArgs e)
{
CheckForItemDuplication(e.Item);
}
private void CheckForItemDuplication(Item item){
if (Service.IsDuplicateItem(item))
{
View.RedirectWithNotification(BuildItemUrl(item), "This item already exists");
}
}
private void DoItemSave(object sender, SaveItemEventArgs e)
{
DoItemIsDuplicateCheck(this, e.ToItemDuplicateEventArgs());
Service.Save(e.Item);
}
}
Here's my test for ensuring that my presenter behaves properly when OnItemIsDuplicateCheck is raised from the view:
[Test]
public void presenter_checking_for_existing_item_should_call_redirect_if_found()
{
var service = new Mock<IItemService>();
var view = new Mock<IItemNewView>();
var presenter = new ItemNewPresenter (service.Object, view.Object);
var onCheckExistingHandler = view.CreateEventHandler <CheckItemDuplicateEventArgs>();
view.Object.OnExistingDenominatorCheck += onCheckExistingHandler;
var eventArgs = new CheckItemDuplicateEventArgs();
service.Setup(s => s.IsDuplicate(It.Is<CheckItemDuplicateEventArgs>(c => c.Equals(eventArgs)))).Returns(true);
onCheckExistingHandler.Raise(eventArgs);
view.Verify(v => v.RedirectWithNotification(It.IsAny<String>(), It.IsAny<string>()), Times.Once());
service.Verify();
}
For consistency, I would like to have the same duplicate check fired when the View raises the OnSave event. My question is around how I am supposed to write my test when one of the methods I want to verify (CheckForItemDuplication) is declared on the class under test. The alternative to verifying the method invocation on the SUT (bad) would be to write my save test with lots of duplicated code (setup and assertion of all my mocks would be copied from the above test) and it also makes the unit test less focused.
[Test]
public void presenter_saving_item_should_check_for_dupe_and_save_if_not_one() {
//duplicate mocks/setups/asserts from duplicate check fixture
//additional mocks/setups/asserts to test save logic
}
I think TDD would suggest pulling this private method out into a separate class that collaborates with my Presenter and would be injected via DI. But adding another dependency to my Presenter for functionality that doesn't seem worthy of being a freestanding abstraction *and*represents an internal implementation detail of my Presenter seems...well...crazy. Am I way off base here? There must be some design pattern or refactoring I can apply that would avoid the need to turn a private method into a dependency.
What I have done sometimes, when confronted with this dilemma, is to extract the function, make an internal constructor with the object as argument, AND a public constructor without. The public ctor is forwarded to the internal with a new object such as:
public class ClassThatUseInjection
{
private readonly SomeClass _injectedClass;
public ClassThatUseInjection(): this(new SomeClass()) {}
internal ClassThatUseInjection(SomeClass injectedClass)
{
_injectedClass = injectedClass;
}
}
public class SomeClass
{
public object SomeProperty { get; set; }
}
Thus, you can use the empty constructor from outside, and the other constructor for when you want to inject a stubbed argument for testpurposes. As long as the empty constructor only forwards the call without any logic of its own, you can still test it, like it has only one constructor.
I would go with testing the class as is by adding the duplicate setup code. Once that test is passing and you are confident all test cases are covered you can then refactor your test code to remove duplication.
You can move the dependencies (service and view) to private fields, then add a method to create the SUT:
private Mock<IItemService> _service;
private Mock<IItemNewView> _view;
private PresenterBase<IItemNewView> CreateSUT()
{
_service = new Mock<IItemService>();
_view = new Mock<IItemNewView>();
return new ItemNewPresenter (service.Object, view.Object);
}
(I think most people would prefer to initialize the Mock objects in the Setup method.)
Call the CreateSUT from your tests and now there is a little less duplication. Then you may want to add private method(s) for creating the event handler / raising the event as long as it is something that is being done the same or similar in more than one tests case.
Having this CreateSUT method cuts down on the amount of test code that is calling your constructor making it easier in the future if you were to add / remove / change dependencies. If you treat your test code like any other code and use the DRY principle when you see duplication it can result in more explicit, easier to read, maintainable test code. Dealing with very similar setup and test context is a common issue with unit testing and should not always change how the class being tested is/was designed.
I'll be interested if there are better answers, as I encounter this all the time.
The alternative to verifying the method invocation on the SUT (bad) would be to write my save test with lots of duplicated code (setup and assertion of all my mocks would be copied from the above test) and it also makes the unit test less focused.
I'm not sure why you feel it makes the test less focused, but in your shoes I would do exactly what it sounds like you don't want to do--have duplicated setup code to test isolated cases for the SUT. You are testing the external behavior of the SUT with the test you supplied, which seems exactly right to me.
I am personally not a fan of exposing more than is necessary from a class and/or making behavior that should be the responsibility of the SUT into a dependency just to facilitate testing. The "natural boundry" of the class's responsibility should not be violated just because you want to test it.
It is easier to unit-test the calculation of the url than to unit-test that redirection has occured.
If i understood you corretly you want to test that the mvp-s CheckForItemDuplication() redirects to a certain url by raising
the view-mock-s OnItemIsDuplicateCheck event.
private void CheckForItemDuplication(Item item)
{
if (Service.IsDuplicateItem(item))
{
View.RedirectWithNotification(BuildItemUrl(item),
"This item already exists");
}
}
In my opinion you are doing to much.
What if you rewrite your code as
internal protected GetErrorUrlForItem(Item item)
{
if (Service.IsDuplicateItem(item))
{
return BuildItemUrl(item,
"This item already exists");
}
return null;
}
private void CheckForItemDuplication(Item item)
{
var result = GetErrorUrlForItem(item);
if (result != null)
{
View.RedirectWithNotification(result);
}
}
In the unittest just test the internal method GetErrorUrlForItem(). You have to use the InternalsVisibleTo attribute to allow accessing the internal method.

Categories