raise event Action in moq - c#

I have structure as below. I want to test if LoadData is called when ViewLoaded event is triggered.
public interface ISetupView
{
event Action ViewLoaded;
}
public class BaseSetupController
{
private ISetupView view;
public BaseSetupController(ISetupView view)
{
this.view = view;
view.ViewLoaded += () => { LoadData(); };
}
public virtual void LoadData()
{
}
}
Currently I have test like below, but it is not working. It states that LoadData is never called.
[TestFixture]
public class BaseSetupControllerTests
{
[Test]
public void ViewLoad_LoadDataIsCalled()
{
Mock<ISetupView> view = new Mock<ISetupView>();
Mock<BaseSetupController> controller = new Mock<BaseSetupController>(view.Object);
controller.Setup(x => x.LoadData());
view.Raise(x => x.ViewLoaded += () => { });
controller.Verify(x=>x.LoadData(), Times.Once());
}
}

It seems that I just needed to create controller.Object before raising event:
var obj = controller.Object;
view.Raise(x=>x.ViewLoaded+=null);

Setting the event handler happens in the constructor, which isn't called if you're only mocking the object.
In a unit test, you have one concrete class. Its dependencies are what you'd mock.
Mocking them both basically only tests the mocking framework, not your class.
Since you want to test whether LoadData is called, you're probably interested if the event handler is set to LoadData. That LoadData is actually called when the event is raised is a given, unless you doubt the .NET framework itself.
This question discusses verifying whether an event has a specific subscriber. But it requires reflection and is not easy.

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.

Trying to Unit Test an Event with JustMock

I am trying to write a Unit Test using JustMock that ignores an Event.
I do not want to test the Event itself, as it calls all sorts of internal functions that would require a massive amount of effort to Mock.
Here is a quick bit of example code:
public class Sample
{
public delegate void OneParameterFunction(int someVar);
public event OneParameterFunction TheEvent;
public Sample()
{
TheEvent += CallMe;
}
public void CallMe(int someVar)
{
Debug.WriteLine("CallMe was fired with parameter: " + someVar);
}
public void FireEvent()
{
// do stuff, business logic here...
if (TheEvent != null)
TheEvent(3);
}
}
And here is the test I would Love to write, but cannot:
[TestClass]
class EventMocking
{
[TestMethod]
public void DoNothingOnEvent()
{
var s = new Sample();
Mock.Arrange(() => s.TheEvent(Arg.AnyInt))
.DoNothing();
Mock.Arrange(() => s.CallMe(Arg.AnyInt))
.OccursNever();
s.FireEvent();
Mock.Assert(() => s.CallMe(Arg.AnyInt));
}
}
But I receive the following compiler error:
Error 1 The event 'Sample.TheEvent' can only appear on the left hand side of += or -= (except when used from within the type 'Sample') C:\BizObjectTests\EventMocking.cs
Does anyone have any suggestions about how to stop an Event from propagating? I also do not want to Mock.Create<T> for a number of reasons, one being I would again, have to setup a lot more test data/objects.
It's impossible to mock the delegate invocation itself, since it's implemented internally by the JIT.
You have several alternative options. If you raise the event in a method dedicated for that purpose (as in your sample), then you can simply mock that method instead. So, in your sample that becomes:
Mock.Arrange(() => s.FireEvent()).DoNothing();
If that's not possible then you can mock the method that adds handlers to the event (the one called when Sample += ... is invoked). You can do this like so:
var mock = Mock.Create<Sample>(); // we need this just for the following arrangement
Mock.ArrangeSet(() => mock.TheEvent += null).IgnoreInstance().IgnoreArguments().DoNothing();
var real = new Sample(); // TheEvent += CallMe will now do nothing
real.FireEvent(); // TheEvent is empty
Finally, as a third option, you can remove all handlers from the event using reflection at some point where you know the event is just about to be fired, or that no one else will attach to it:
new PrivateAccessor(real).SetField("TheEvent", null);
real.FireEvent(); // TheEvent is null right now
Caveat: this last option is dependent on the compiler implementation. It will work for event declarations in C# code, but will not work for VB events.

Mocking EventHandler

Having defined an interface
public interface IHandlerViewModel {
EventHandler ClearInputText { get; }
}
I would like to test if ClearInputText is invoked by some method.
To do so I do something like this
SomeType obj=new SomeType();
bool clearCalled = false;
var mockHandlerViewModel=new Mock<IHandlerViewModel>();
mockHandlerViewModel.Setup(x => x.ClearInputText).Returns(delegate { clearCalled = true; });
obj.Call(mockHandlerViewModel.Object);//void Call(IHandlerViewModel);
Assert.IsTrue(clearCalled);
which fails. Simply the delegate is not called.
Please help me with this.
The example you give isn't clear. You're essentially testing your own mock.
In a scenario where the mocked proxy is passed as a dependency to an object under test, you do no set up the event handler, you Raise it.
var mockHandlerViewModel = new Mock<IHandlerViewModel>();
var objectUnderTest = new ClassUnderTestThatTakesViewModel(mockHandlerViewModel.Object);
// Do other setup... objectUnderTest should have registered an eventhandler with the mock instance. Get to a point where the mock should raise it's event..
mockHandlerViewModel.Raise(x => x.ClearInputText += null, new EventArgs());
// Next, Assert objectUnderTest to verify it did what it needed to do when handling the event.
Mocks either substitute the event source by using .Raise(), or they substitute an object that will consume another class under test's event (to assert the event was raised), in which case you use .Callback() to record "handling" the event in a local flag variable.

Mocking a C# timer with Moq

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)

Verifying event handler code executed

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.

Categories