2010-06-04 5 views
1

В моем модульном тесте, как я могу проверить, что событие вызвано издеваемым объектом.Проверить, что событие было вызвано издеваемым объектом

У меня есть представление (UI) -> ViewModel -> DataProvider -> ServiceProxy. ServiceProxy выполняет асинхронный вызов для работы с сервером. Когда операция async завершена, вызывается метод в DataProvider (метод обратного вызова передается как параметр метода). Затем метод обратного вызова поднимает и событие, которое прослушивает ViewModel.

Для проверки ViewModel я макетирую DataProvider и проверяю, существует ли обработчик для события, поднятого DataProvider. При тестировании DataProvider я макетирую ServiceProxy, но как я могу проверить, вызван ли метод обратного вызова, и возникает событие.

Я использую RhinoMock 3.5 и синтаксис AAA

Благодаря

- 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); 
    } 
} 

ответ

2

Похоже, у вас есть два различных модульных тестов, чтобы написать:

  1. тест Service Proxy блок: Этот тест будет убедиться, что обратный вызов послал в к ServiceProxy будет называться после завершения асинхронный вызов.

  2. Тестирование модуля поставщика данных: этот тест позволит убедиться, что при вызове определенного метода возникает событие (при условии наличия некоторых подписчиков).

С кем вы ищете помощь?

EDIT:

Для пункта # 1, я не вижу, что ты нужна насмешки. Просто обеспечивают функцию обратного вызова, которая устанавливает некоторую переменную истинным при вызове:

// 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) 

Я не знаю подписи ваших событий/обратных вызовов, поэтому я просто сделал некоторые догадки.

+0

помощь по обоим будет здорово. спасибо – joblot

+0

извините за задержку. для второго теста проблема DoSomethingThatShouldRiaseEvent не является общедоступным методом DataProvider. Это метод обратного вызова, который передается ServiceProxy. спасибо – joblot

+0

Возможно, это поможет, если вы предоставили методы DataProvider и как они взаимодействуют с классом ServiceProxy. Я думаю, что разделение этого на два отдельных модульных теста - хорошее начало. Затем вы можете стать более привлекательным и связать их с интеграционным тестом (хотя только отдельные тесты помогут гарантировать, что отдельные компоненты ведут себя так, как они были разработаны/ожидаются). – PatrickSteele

1

Следующий пример устанавливает вверх 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); 
Смежные вопросы