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.
Related
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.
Imagine that I have have Class1 obj1 = new Class1(). Class1 has many different events. I want to know what event and when does it happened, but I don't want to create event handler for every event of this object. How can I do it?
Example output that I want to see:
13:04:29 Obj1.OnEvent1
13:04:31 Obj1.OnEvent2
13:04:32 Obj1.OnEvent3
13:04:35 Obj1.OnEvent2
......................
P.S.: I am using Visual Studio 2012 Ultimate.
You have to instrument your code using, for example, the Semantic Logging Application Block.
If you follow the established practice of having a protected virtual OnEvent method the fires the *Event* event, you'll find out the the actual event is the OnEvent method is in fact the real event and the *Event* .NET event is just a notification others can subscribe to. And you want to log events and not event subscriptions.
You can have something that subscribes to the events and log it, but you'll also soon find out that you'll want to log more than those events.
If the delegate types of your eventhandler are uniform you can iterate over the events obtained from the type and attach your logging logic to the event. I use a logger class with methods for Subscibe and Unsubscribe (not implemented here)
Logger
public class EventLogger
{
public void Subscribe<T>(T obj)
{
// get the type to iterate over the EventInfo's
var type = typeof (T);
foreach (var eve in type.GetEvents())
{
EventInfo info = eve;
// attach our logging logic
eve.AddEventHandler(obj,
new EventHandler((sender, args) =>
{
Console.WriteLine(
"{0} {1}.{2}",
DateTime.Now,
obj,
info.Name);
}));
}
}
public void Unsubscribe()
{
//todo unsubscribe
}
}
Demo Class
public class Class1
{
// public delegate void MyDelegate(string key, DateTime date, int value);
public event EventHandler Foo;
public event EventHandler Bar;
// public event MyDelegate Cancel;
public void Raise()
{
this.Bar(null, EventArgs.Empty);
// this.Cancel(null, DateTime.Now, 4);
}
}
Usage
var c = new Class1();
c.Bar += (sender, eventArgs) => { Console.WriteLine("bar"); };
// have our logger ready
var logger = new EventLogger();
// attach logging to a specific instance
logger.Subscribe(c);
// raise our events
c.Raise();
Notice that we only can handle delegates of the type EventHandler. (I commented the delegate MyDelegate because that would break this simple implementation). If you have events that use different delegates you either need to build a switch statement in the Subscribe method to handle each differen type or implement a method to generate a dynamic assembly that can handle the delegate as shown here.
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.
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 am using RhinoMocks, and I have a Mock which has a property I need to behave as a real property - updating its value when set, and also trigger PropertyChanged when the property is changed.
The interface of the mocked object is in essence this:
public interface IFoo
{
event PropertyChangedEventHandler PropertyChanged;
int Bar { get; set; }
}
When creating the mock I set PropertyBehavior - which makes it actually update its faked value:
var mocks = new MockRepository();
var fakeFoo = mocks.DynamicMock<IFoo>();
SetupResult.For(fakeFoo.Bar).PropertyBehavior();
But when I update the value PropertyChanged isn't triggered. Now, the interface doesn't implement the INotifyPropertyChanged interface as it is an interface.. How can I make PropertyChanged triggered?
The role of listener and mutator may sometimes be combined in the same class (e.g. in an adapter), but both roles should not be tested together.
In one test, you merely verify that your listening class reacts to the PropertyChanged event as designed. You don't care about what caused the property to change in that test:
[Test]
public void Updates_Caption_when_Bar_PropertyChanged()
{
var foo = MockRepository.GenerateStub<IFoo>();
foo.Bar = "sometestvalue1";
var underTest = new UnderTest(foo);
// change property and raise PropertyChanged event on mock object
foo.Bar = "sometestvalue2";
foo.Raise(x=>x.PropertyChanged+=null,
foo,
new PropertyChangedEventArgs("Bar"));
// assert that the class under test reacted as designed
Assert.AreEqual("sometestvalue2", underTest.Caption);
// or if the the expected state change is hard to verify,
// you might just verify that the property was at least read
foo.AssertWasCalled(x => { var y = foo.Bar; } );
}
In another test, you verify that your class plays its mutator role as designed:
[Test]
public void Reset_clears_Foo_Bar()
{
var foo = MockRepository.GenerateStub<IFoo>();
foo.Bar = "some string which is not null";
var underTest = new UnderTest(foo);
underTest.Reset();
// assert that the class under test updated the Bar property as designed
Assert.IsNull(foo.Bar);
}
This way, it is never necessary to put real logic into your mock objects like you are trying to do. This does require that you design your classes for testability; it is hard to add such tests to existing classes. Hence the practice of test driven development.
I'm not an expert in RhinoMocks, but I wouldn't try to do that with any of the mock-framework I know (TypeMock I know the most).
I would implement something like:
public class FooFake: IFoo
{
public event PropertyChangedEventHandler PropertyChanged;
int _bar;
public int Bar
{
set
{
if( PropertyChanged != null )
PropertyChanged();
_bar = value;
}
get
{
return _bar;
}
}
}
Sorry. Nothing really clever. But I like this kind of stub as they can be resused.