Verify an event was raised by mocked object
In my unit test how can I verify that an event is raised by the mocked object.
I have a View(UI) --> ViewModel --> DataProvider --> ServiceProxy. ServiceProxy makes async call to serivce operation. When async operation is complete a method on DataProvider is called (callback method is passed as a method parameter). The callback method then raise and event which ViewModel is listening to.
For ViewModel test I mock DataProvider and verify that handler exists for event raised by DataProvider. When testing DataProvider I mock ServiceProxy, but how can I test that callback method is called and event is raised.
I am using RhinoMock 3.5 and AAA syntax
Thanks
-- DataProvider --
public partial class DataProvider
{
public event EventHandler<EntityEventArgs<ProductDefinition>> GetProductDefinitionCompleted;
public void GetProductDefinition()
{
var service = IoC.Resolve<IServiceProxy>();
service.GetProductDefinitionAsync(GetProductDefinitionAsyncCallback);
}
private void GetProductDefinitionAsyncCallback(ProductDefinition productDefinition, ServiceError error)
{
OnGetProductDefinitionCompleted(this, new EntityEventArgs<ProductDefinition>(productDefinition, error));
}
protected void OnGetProductDefinitionCompleted(object sender, EntityEventArgs<ProductDefinition> e)
{
if (GetProductDefinitionCompleted != null)
GetProductDefinitionCompleted(sender, e);
}
}
-- ServiceProxy --
public class ServiceProxy : ClientBase<IService>, IServiceProxy
{
public void GetProductDefinitionAsync(Action<ProductDefinition, ServiceError> callback)
{
Channel.BeginGetProductDefinition(EndGetProductDefinition, callback);
}
private void EndGetProductDefinition(IAsyncResult result)
{
Action<ProductDefinition, ServiceError> callback =
result.AsyncState as Ac开发者_开发知识库tion<ProductDefinition, ServiceError>;
ServiceError error;
ProductDefinition results = Channel.EndGetProductDefinition(out error, result);
if (callback != null)
callback(results, error);
}
}
It sounds like you have two different unit tests to write:
Service Proxy unit test: This test will make sure that the callback sent in to the ServiceProxy will be called upon completion of the async call.
Data Provider unit test: This test will make sure that when a certain method is called, an event is raised (assuming there were some subscribers).
Which one are you looking for help on?
EDIT:
For item #1, I don't see that you'd need any mocking. Simply provide a callback that sets some variable to true when called:
// arrange
IServiceProxy serviceProxy = new ServiceProxy();
bool callbackMade;
// act
serviceProxy.GetDataAsync(() => callbackMade = true);
// assert
Assert.IsTrue(callbackMade);
For item #2, again, just subscribe to the event in your unit test and make sure the event is called:
// arrange
DataProvider dp = new DataProvider();
bool eventRaised;
dp.DataReturned += (s,e) => eventRaised = true;
// act
dp.DoSomethingThatShouldRaiseEvent();
// assert
Assert.IsTrue(eventRaised)
I don't know the signatures of your events/callbacks so I just made some guesses.
The following example sets up an IService
stub which will simply invoke any callback that is passed to it when IService.AsyncOperationWithCallBack(Action callback)
is called.
// arrange
var serviceStub = MockRepository.GenerateStub<IService>();
serviceStub.Stub(x => x.AsyncOperationWithCallBack(Arg<Action>.Is.NotNull))
.WhenCalled(
invokation =>
{
var callback = (Action)invokation.Arguments[0];
callback();
});
var dataProvider = new DataProvider(serviceStub);
// act
bool raised = false;
dataProvider.MyEvent += delegate { raised = true; };
dataProvider.DoSomething();
// assert
serviceStub.AssertWasCalled(
x=>x.AsyncOperationWithCallBack(Arg<Action>.Is.NotNull));
Assert.IsTrue(raised);
精彩评论