Handling event of recursively created Mock in Moq - c#

I'm trying to use recursive mocking feature from the Moq framework but it doesn't work as I expect it to work.
using System;
using NUnit.Framework;
using Moq;
namespace MoqTest
{
public interface IParent
{
IChild Child { get; }
}
public interface IChild
{
event EventHandler SomethingHappened;
}
[TestFixture]
public class UnitTest
{
[Test]
public void RecursiveMockTest()
{
// Arrange
bool isEventHandled = false;
var parentMock = new Mock<IParent>();
parentMock.DefaultValue = DefaultValue.Mock;
var parent = parentMock.Object;
parent.Child.SomethingHappened +=
(sender, args) =>
{
isEventHandled = true;
};
// Act
parentMock.Raise(x => x.Child.SomethingHappened += null, EventArgs.Empty);
// Assert
Assert.IsTrue(isEventHandled);
}
}
}
Could please someone explain to me why SomethingHappened is never handled? I have an assumption that references of parent.Child.SomethingHappened and x.Child.SomethingHappened are not equals. If so then why it's not the same?

It's all correct, you need the following:
[Test]
public void RecursiveMockTest()
{
// Arrange
bool isEventHandled = false;
var parentMock = new Mock<IParent>();
parentMock.DefaultValue = DefaultValue.Mock;
var parent = parentMock.Object;
// get the actual mock which was automatically setup for you
var childMock = Mock.Get(parent.Child);
parent.Child.SomethingHappened +=
(sender, args) =>
{
isEventHandled = true;
};
// Act on the mock which was setup for you
childMock.Raise(x => x.SomethingHappened += null, EventArgs.Empty);
// Assert
Assert.IsTrue(isEventHandled);
}

Related

Raising complex event using Moq in C#

The following code should be self explanetory: we have an adaptor, who consumes events from the transport (layer), which holds the MessageRegistrar (object type because we can't tell it's type, and basically because this is legacy code :-) ). The transport layer have a concrete which have an event.
I want to test a case where the event is triggered, so..
After hours of trying to figure why it won't pass, I present the following challenge:
[TestFixture]
public class AdaptorTests
{
public delegate void TracksEventHandler(object sender, List<int> trklst);
public class MyEventHolder
{
public virtual event TracksEventHandler EventName;
}
public interface ITransport
{
object MessageRegistrar { get; }
}
public class MyTransport : ITransport
{
private readonly MyEventHolder m_eventHolder;
public MyTransport(MyEventHolder eventHolder)
{
m_eventHolder = eventHolder;
}
public virtual object MessageRegistrar
{
get { return m_eventHolder; }
}
}
public class MyAdaptor
{
private readonly ITransport m_transport;
public MyAdaptor(ITransport transport)
{
EventTriggered = false;
m_transport = transport;
}
public void Connect()
{
MyEventHolder eventHolder = m_transport.MessageRegistrar as MyEventHolder;
if (eventHolder != null)
eventHolder.EventName += EventHolderOnEventName;
}
private void EventHolderOnEventName(object sender, List<int> trklst)
{
EventTriggered = true;
}
public bool EventTriggered { get; private set; }
}
[Test]
public void test1()
{
Mock<MyEventHolder> eventHolderMock = new Mock<MyEventHolder> {CallBase = true};
Mock<MyTransport> transportMock = new Mock<MyTransport>(eventHolderMock.Object) {CallBase = true};
MyAdaptor adaptor = new MyAdaptor(transportMock.Object);
adaptor.Connect();
MyEventHolder eventHolder = transportMock.Object.MessageRegistrar as MyEventHolder;
Mock.Get(eventHolder).Raise(eh => eh.EventName += null, new List<int>());
Assert.IsTrue(adaptor.EventTriggered);
}
[Test]
public void test2()
{
Mock<MyEventHolder> eventHolderMock = new Mock<MyEventHolder> { CallBase = true };
Mock<MyTransport> transportMock = new Mock<MyTransport>(eventHolderMock.Object) { CallBase = true };
MyAdaptor adaptor = new MyAdaptor(transportMock.Object);
adaptor.Connect();
MyEventHolder eventHolder = transportMock.Object.MessageRegistrar as MyEventHolder;
Mock.Get(eventHolder).Raise(eh => eh.EventName += null, null, new List<int>());
Assert.IsTrue(adaptor.EventTriggered);
}
}
My question is: why wont the test (at least one of them) pass?
EDIT #151217-0822 Addded 'adaptor.Connect()' to the original post (still won't fix the issue).
WORKAROUND
Credits to #Patrick Quirk: Thanks!!
For those encountering the same issue: after I understood what Patrick-Quirk detected, and trying couple of failed workarounds, I've ended up adding the following verified fix: 'eventHolder.FireEventNameForTestings(new List());':
public class MyEventHolder
{
public virtual event TracksEventHandler EventName;
public virtual void FireEventNameForTestings(List<int> trklst)
{
TracksEventHandler handler = EventName;
if (handler != null)
handler(this, trklst);
}
}
[Test]
public void test3()
{
Mock<MyEventHolder> eventHolderMock = new Mock<MyEventHolder> { CallBase = true };
Mock<MyTransport> transportMock = new Mock<MyTransport>(eventHolderMock.Object) { CallBase = true };
MyAdaptor adaptor = new MyAdaptor(transportMock.Object);
adaptor.Connect();
MyEventHolder eventHolder = transportMock.Object.MessageRegistrar as MyEventHolder;
eventHolder.FireEventNameForTestings(new List<int>());
Assert.IsTrue(adaptor.EventTriggered);
}
HTH..
It seems that CallBase and Raise() have an unexpected (to me) interaction.
When you are attaching an event handler to a virtual event on a mock, you go through this code in Moq:
if (invocation.Method.IsEventAttach())
{
var delegateInstance = (Delegate)invocation.Arguments[0];
// TODO: validate we can get the event?
var eventInfo = this.GetEventFromName(invocation.Method.Name.Substring(4));
if (ctx.Mock.CallBase && !eventInfo.DeclaringType.IsInterface)
{
invocation.InvokeBase();
}
else if (delegateInstance != null)
{
ctx.AddEventHandler(eventInfo, (Delegate)invocation.Arguments[0]);
}
return InterceptionAction.Stop;
}
You can see that if CallBase is true, then it will add your handler to the concrete object's event (via invocation.InvokeBase()). If CallBase is false, it will add it to an invocation list on the mock (via AddEventHandler). Now let's look at the code for Raise(), which gets the event object from the Expression and then calls DoRaise():
internal void DoRaise(EventInfo ev, EventArgs args)
{
// ... parameter validation
foreach (var del in this.Interceptor.InterceptionContext.GetInvocationList(ev).ToArray())
{
del.InvokePreserveStack(this.Object, args);
}
}
See the call to GetInvocationList()? That retrieves the invocation list from the mock that I mentioned above. This code never invokes the actual event on the base object.
So, it seems there's no way to raise an event on a mocked object where CallBase is set to true.
The only workaround I see, if you require CallBase being true, is to add a method to your concrete MyEventHolder to trigger your event. Obviously what you posted is a simplified example so I can't give you more guidance than that, but hopefully I've shown you why what you have does not work.

nunit testing of method which calls other method

Am very new to nunit.below is the business unit code
public enum HighlightType
{
IP,
Item,
Address
}
public class UniformGridHighlighting
{
public static event HighlightingChangedDelegate HighlightingChanged;
private static List<string> _highlightedIPs = new List<string>();
private static List<long> _highlightedItems = new List<long>();
private static ContactInfoType _highlightedAddress;
public static void ClearIPHighlighting()
{
_highlightedIPs.Clear();
OnHighlightingChanged(HighlightType.IP);
}
private static void OnHighlightingChanged(HighlightType type)
{
if (HighlightingChanged != null)
{
HighlightingChanged(type);
}
}
}
I need to write unit test cases for ClearIPHighlighting. How do i proceed.
[Test(Description = "to ")]
public void ClearIPHighlightingTets()
{
UniformGridHighlighting.ClearIPHighlighting();
//How to call method
}
Given the current setup you can only test that the event is triggered.
[Test()]
public void ThatTheEventIsTriggeredWhenTheListIsCleared()
{
// Arrange
bool eventTriggered = false;
UniformGridHighlighting.HighlightingChanged += _ => { eventTriggered= true; };
//Act
UniformGridHighlighting.ClearIPHighlighting();
//Assert:
Assert.IsTrue(eventTriggered);
}
And that it's of the right type
[Test(Description = "to ")]
public void ThatTheEventIsTriggeredWithTheIPArgumentWhenTheIPListIsCleared()
{
// Arrange
HighlightType? type = null;
UniformGridHighlighting.HighlightingChanged += x => { type = x; };
//Act
UniformGridHighlighting.ClearIPHighlighting();
//Assert:
Assert.AreEqual(s, HighlightType.IP);
}
To test that your previous highlight was removed is going to be harder:
[Test]
public void ThatTheIpIsNotHighlightedIfTheListWasCleared()
{
UniformGridHighlighting.HighlightIP("1.1.1.1");
//Act
UniformGridHighlighting.ClearIPHighlighting();
UniformGridHighlighting.Highlihst(Grid);
//Assert:
//Go through the grid to figure out that the IP was not highlighted. The below is a total guess:
bool wasHighlighted = Grid.Rows.Any(row => row.Cells.Any(Cell.Highlighted));
Assert.Isfalse(wasHighlighted);
}

unit testing a class with event and delegate

I am new to testing please help.
I have the following class
public delegate void OnInvalidEntryMethod(ITnEntry entry, string message);
public class EntryValidator
{
public event OnInvalidEntryMethod OnInvalidEntry;
public bool IsValidEntry(ITnEntry entry, string ticker)
{
if (!IsFieldValid(entry, ticker.Trim().Length.ToString(), "0"))
return false;
return true;
}
private bool IsFieldValid(ITnEntry entry, string actual, string invalidValue)
{
if (actual == invalidValue)
{
RaiseInvalidEntryEvent(entry);
return false;
}
return true;
}
private void RaiseInvalidEntryEvent(ITnEntry entry)
{
if (OnInvalidEntry != null)
OnInvalidEntry(entry, "Invalid entry in list: " + entry.List.Name + ".");
}
}
I have written the test case so far but am struggling with the event and delegate as shown below
[TestFixture]
public class EntryValidatorTests
{
private EntryValidator _entryValidator;
private FakeTnEntry _selectedEntry;
private string _ticker;
[SetUp]
public void Setup()
{
_entryValidator = new EntryValidator();
_ticker = "BOL";
}
private FakeTnEntry MakeEntry(string ticker)
{
return new FakeTnEntry { Ticker = ticker};
}
[Test]
public void IsValidEntry_WithValidValues()
{
_selectedEntry = MakeEntry(_ticker);
Assert.IsTrue(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
}
[Test]
public void IsValidEntry_WithInValidTicker()
{
_selectedEntry = MakeEntry("");
Assert.IsFalse(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
}
}}
Please can someone help? Thanks..
It's probably simplest just to subscribe to the event using an anonymous method:
[Test]
public void IsValidEntry_WithValidValues()
{
_selectedEntry = MakeEntry(_ticker);
_entryValidator.OnInvalidEntry += delegate {
Assert.Fail("Shouldn't be called");
};
Assert.IsTrue(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
}
[Test]
public void IsValidEntry_WithInValidTicker()
{
bool eventRaised = false;
_selectedEntry = MakeEntry("");
_entryValidator.OnInvalidEntry += delegate { eventRaised = true; };
Assert.IsFalse(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
Assert.IsTrue(eventRaised);
}
In the second test you might want to validate that the event arguments were as expected too.
Also note that "invalid" is one word - so your test should be IsValidEntry_WithInvalidTicker. I'd also not bother with the setup - I'd just declare new local variables in each test.
I would restructure your class to make the RaiseInvalidEntryEvent virtual so it can be mocked in your IsValidEntry_WithInValidTicker and then verified it was called when the ticket was invalid.
Then I would have another test that verified RaiseInvalidEntryEvent called the anon delegate separately.
Unit tests should be as atomic as possible, and you would want to verify both of these behaviors in different tests.
public delegate void OnInvalidEntryMethod(ITnEntry entry, string message);
public class EntryValidator
{
public event OnInvalidEntryMethod OnInvalidEntry;
public bool IsValidEntry(ITnEntry entry, string ticker)
{
if (!IsFieldValid(entry, ticker.Trim().Length.ToString(), "0"))
return false;
return true;
}
private bool IsFieldValid(ITnEntry entry, string actual, string invalidValue)
{
if (actual == invalidValue)
{
RaiseInvalidEntryEvent(entry);
return false;
}
return true;
}
public virtual void RaiseInvalidEntryEvent(ITnEntry entry)
{
if (OnInvalidEntry != null)
OnInvalidEntry(entry, "Invalid entry in list: " + entry.List.Name + ".");
}
}
// Had to reverse engineer the following since they were not available in the question
public interface ITnEntry
{
Ticket List { get; set; }
string Ticker { get; set; }
}
public class TnEntry : ITnEntry
{
public Ticket List { get; set; }
public string Ticker { get; set; }
}
public class Ticket
{
public string Name { get; set; }
}
NOTE: Some OOP evangalists have fits when things are declared public instead of private, basically unit testing and TDD have some requirements that pure OOP is at odds with. I've made RaiseInvalidEntryEvent public for simplicity, but normally I would make this internal and then expose the assembly to the unit test via InternalsVisibleTo. I've been doing TDD for the last 4 years now and rarely use private anymore.
And the unit tests would quickly be (note, this is using the MSTEST framework from VS2012)
[TestClass]
public class UnitTest1
{
#region TestHelpers
private ITnEntry MakeEntry(string ticker)
{
return new TnEntry {Ticker = ticker, List = new Ticket()};
}
#endregion
[TestMethod]
public void IsValidEntry_WithValidValues_ReturnsTrue()
{
// ARRANGE
var target = new EntryValidator();
var selectedEntry = MakeEntry("BOL");
// ACT
bool actual = target.IsValidEntry(selectedEntry, selectedEntry.Ticker);
// ASSERT
Assert.IsTrue(actual);
}
[TestMethod]
public void IsValidEntry_WithInValidTicker_ReturnsFalse()
{
// ARRANGE
var target = new EntryValidator();
var selectedEntry = MakeEntry("");
// ACT
bool actual = target.IsValidEntry(selectedEntry, selectedEntry.Ticker);
// ASSERT
Assert.IsFalse(actual);
}
[TestMethod]
public void IsValidEntry_WithInvalidTicker_RaisesEvent()
{
// ARRANGE
// generate a dynamic mock which will stub all virtual methods
var target = Rhino.Mocks.MockRepository.GenerateMock<EntryValidator>();
var selectedEntry = MakeEntry("");
// ACT
bool actual = target.IsValidEntry(selectedEntry, selectedEntry.Ticker);
// ASSERT
// assert that RaiseInvalidEntryEvent was called
target.AssertWasCalled(x => x.RaiseInvalidEntryEvent(Arg<ITnEntry>.Is.Anything));
}
[TestMethod]
public void RaiseInvalidEntryEvent_WithValidHandler_CallsDelegate()
{
// ARRANGE
var target = new EntryValidator();
var selectedEntry = MakeEntry("");
bool delegateCalled = false;
// attach a handler to set delegateCalled to true
target.OnInvalidEntry += delegate
{
delegateCalled = true;
};
// ACT
target.IsValidEntry(selectedEntry, selectedEntry.Ticker);
// ASSERT
Assert.IsTrue(delegateCalled);
}
}
Your test should subscribe to the event OnInvalidEntry with a dummy method, call IsValidEntry and check the result.

How can I mock this asynchronous method?

I have a class that roughly looks like this:
public class ViewModel
{
public ViewModel(IWebService service)
{
this.WebService = service;
}
private IWebService WebService{get;set;}
private IEnumerable<SomeData> MyData{get;set;}
private void GetReferenceData()
{
this.WebService.BeginGetStaticReferenceData(GetReferenceDataOnComplete, null);
}
private void GetReferenceDataOnComplete(IAsyncResult result)
{
this.MyData = this.WebService.EndGetStaticReferenceData(result);
}
.
.
.
}
I want to mock my IWebService interface so that when BeginGetStaticReferenceData is called it is able to call the callback method. I'm using Moq and I can't work out how to do this. My unit test set up code looks something like:
//Arrange
var service = new Mock<IWebService>();
service.Setup(x => x.BeginGetStaticReferenceData(/*.......don't know.....*/));
service.Setup(x => x.EndGetStaticReferenceData(It.IsAny<IAsyncResult>())).Returns(new List<SomeData>{new SomeData{Name="blah"}});
var viewModel = new ViewModel(service.Object);
.
.
Here's how:
[TestMethod]
public void Test10()
{
var expectedData = new[]{new SomeData(), new SomeData()};
AsyncCallback callback = null;
IAsyncResult ar = new Mock<IAsyncResult>().Object;
var webServiceStub = new Mock<IWebService>();
webServiceStub
.Setup(ws => ws.BeginGetStaticReferenceData(It.IsAny<AsyncCallback>(), null))
.Callback((AsyncCallback cb, object state) => callback = cb)
.Returns(ar);
webServiceStub
.Setup(ws => ws.EndGetStaticReferenceData(It.IsAny<IAsyncResult>()))
.Returns(expectedData);
var sut = new ViewModel(webServiceStub.Object);
sut.DoIt();
callback(ar);
Assert.AreEqual(expectedData, sut.MyData);
}
This test assumes a slightly modified ViewModel where I added a few public members to have something against which to test:
public class ViewModel
{
public ViewModel(IWebService service)
{
this.WebService = service;
}
public IEnumerable<SomeData> MyData { get; set; }
public void DoIt()
{
this.GetReferenceData();
}
private IWebService WebService { get; set; }
private void GetReferenceData()
{
this.WebService.BeginGetStaticReferenceData(GetReferenceDataOnComplete, null);
}
private void GetReferenceDataOnComplete(IAsyncResult result)
{
this.MyData = this.WebService.EndGetStaticReferenceData(result);
}
}
This article contains a very good explanation on how to test async methods using Rhino Mocks - I'm sure it can be easily adapted to use Moq instead.

Verifying event registration using Moq

I'm developing an asp.net (classic) application trying to implement the MVP pattern using this example. In trying to unit test my presenter and using the following pattern, the psuedocode for which looks like so
//base view interface
public interface IView
{
event EventHandler Init;
event EventHandler Load;
bool IsPostBack { get; }
void DataBind();
bool IsValid { get;}
}
//presenter psuedo code
public class SomePresenter
{
public SomePresenter(ISomeDomainService service, IView someView)
{
...
//HOW DO WE TEST/VERIFY THAT THIS REGISTRATION OCCURS?
someView.Init += OnInit;
someView.Load += OnLoad;
}
}
...
//consuming code that exercises the above code, that needs to be tested
var presenter = new SomePresenter(someDomainService, someView);
How do I verify that the presenter is doing what is expected i.e. registering for the Init and Load events? While this is easily done in the Phil Haack's example using Rhino mocks...
[Test]
public void VerifyAttachesToViewEvents()
{
viewMock.Load += null;
LastCall.IgnoreArguments();
viewMock.PostSaved += null;
LastCall.IgnoreArguments();
mocks.ReplayAll();
new PostEditController(viewMock,
this.dataServiceMock);
mocks.VerifyAll();
}
... how can we do this using MOQ?
The moq 4.13 introduced this feature. Now it is possible to verify if add\remove has been invoked. Therefore four new methods have been introduced:
SetupAdd
SetupRemove
VerifyAdd
VerifyRemove
Example
var mock = new Mock<IAdder<EventArgs>>();
mock.SetupAdd(m => m.Added += (sender, args) => { });
mock.Object.Added += (sender, args) => { };
mock.Object.Added += (sender, args) => { };
mock.VerifyAdd(m => m.Added += It.IsAny<EventHandler>(), Times.Exactly(2));
NB: Notice that in order to verify at least one setup should be added. The reason is to keep backward compatibility with the older version of moq.
It would appear that this functionality is not currently available in moq, but may appear in a future version (I had a look in the 4.0.812.4 beta, but it doesn't seem to be there).
It may be worth asking the question, "why does SomePresenter need to subscribe to the View's Load and Init events?" Presumably it is because the SomePresenter class needs to respond to those events. So it might be better to use the Raise method on your Mock<IView> to raise the Load and Init events, and then assert that SomePresenter did the right thing in response to them.
I know it's maybe too late for #Dilip, but this answer can be helpful for those who are trying to do the same.
Here is the test class
public delegate void SubscriptionHandler<T>(string name, T handler);
public class SomePresenterTest
{
[Test]
public void Subscription_Test()
{
var someServiceMock = new Mock<ISomeDomainService>();
var viewMock = new Mock<IView>();
//Setup your viewMock here
var someView = new FakeView(viewMock.Object);
EventHandler initHandler = null;
someView.Subscription += (n, h) => { if ((nameof(someView.Init)).Equals(n)) initHandler=h; };
Assert.IsNull(initHandler);
var presenter = new SomePresenter(someServiceMock.Object, someView);
Assert.IsNotNull(initHandler);
Assert.AreEqual("OnInit", initHandler.Method?.Name);
}
}
FakeView is a decorator implemented as follow (pay attention to Events:Init/Load{add;remove}):
public class FakeView : IView
{
public event SubscriptionHandler<EventHandler> Subscription;
public event SubscriptionHandler<EventHandler> Unsubscription;
private IView _view;
public FakeView(IView view)
{
Assert.IsNotNull(view);
_view = view;
}
public bool IsPostBack => _view.IsPostBack;
public bool IsValid => _view.IsValid;
public event EventHandler Init
{
add
{
Subscription?.Invoke(nameof(Init), value);
_view.Init += value;
}
remove
{
Unsubscription?.Invoke(nameof(Init), value);
_view.Init -= value;
}
}
public event EventHandler Load
{
add
{
Subscription?.Invoke(nameof(Load), value);
_view.Init += value;
}
remove
{
Unsubscription?.Invoke(nameof(Load), value);
_view.Init -= value;
}
}
public void DataBind()
{
_view.DataBind();
}
}
I spent some time with this question and the solution which I'm using in my project is:
Unit test:
// Arrange
TestedObject.Setup(x => x.OnEvent1());
TestedObject.Setup(x => x.OnEvent2());
// Act
TestedObject.Object.SubscribeEvents();
TestedObject.Raise(x => x.Event1 += null);
TestedObject.Raise(x => x.Event2 += null);
// Assert
TestedObject.Verify(x => x.OnEvent1(), Times.Once());
TestedObject.Verify(x => x.OnEvent2(), Times.Once());
Tested method:
this.Event1 += OnEvent1;
this.Event2 += OnEvent2;
So, first you have to mock the methods which you will assign the events, after you call the method which you want to test, and finally raise all subscribed events. If the event is really subscribed, you can check with Moq if the assigned method is called.
GLHF!

Categories