Убедитесь, что событие было поднято высмеиваемым объектом
-
24-10-2019 - |
Вопрос
В моем модульном тесте, как я могу проверить, что событие поднимается высмеиваемым объектом.
У меня есть представление (UI) -> ViewModel -> DataProvider -> ServiceProxy. ServiceProxy делает асинхронный призыв к операции Serivce. Когда Async Operation завершается методом на DataProvider вызывается (метод обратного вызова передается в виде параметра метода). Метод обратного вызова затем поднимает и событие, которое слушает ViewModel.
Для тестирования ViewModel я вытекает DataProvider и убедитесь, что обработчик существует для события, поднятого DataProvider. При тестировании DataProvider я издевается над ServiceProxy, но как я могу проверить этот метод обратного вызова и повышается событие.
Я использую Rhinomock 3.5 и AAA Syntax
Спасибо
-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 Action<ProductDefinition, ServiceError>;
ServiceError error;
ProductDefinition results = Channel.EndGetProductDefinition(out error, result);
if (callback != null)
callback(results, error);
}
}
Решение
Похоже, у вас есть два разных модульных теста для написания:
Прокси -тест на обслуживание: этот тест убедится, что обратный вызов, отправленный в ServiceProxy, будет вызван после завершения асинхронного вызова.
Единый тест поставщика данных: этот тест убедится, что когда будет вызван определенный метод, появляется событие (при условии, что были некоторые подписчики).
На каком вы ищете помощь?
РЕДАКТИРОВАТЬ:
Для пункта № 1 я не вижу, чтобы вам понадобилось лишнее насмешливое. Просто предоставьте обратный вызов, который устанавливает некоторую переменную на True при вызове:
// arrange
IServiceProxy serviceProxy = new ServiceProxy();
bool callbackMade;
// act
serviceProxy.GetDataAsync(() => callbackMade = true);
// assert
Assert.IsTrue(callbackMade);
Для пункта № 2, опять же, просто подпишитесь на событие в вашем модульном тесте и убедитесь, что событие называется:
// arrange
DataProvider dp = new DataProvider();
bool eventRaised;
dp.DataReturned += (s,e) => eventRaised = true;
// act
dp.DoSomethingThatShouldRaiseEvent();
// assert
Assert.IsTrue(eventRaised)
Я не знаю подписи ваших событий/обратных вызовов, поэтому я только что сделал несколько предположений.
Другие советы
Следующий пример устанавливает IService
Заглушка, который просто вызовет любой обратный вызов, который передается ему, когда IService.AsyncOperationWithCallBack(Action callback)
называется.
// 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);