2010-05-28 3 views
0

У меня есть класс прокси-сервера службы, который делает вызов asyn для обслуживания. Я использую метод обратного вызова для передачи результатов обратно в мою модель представления.RhinoMocks Проверка метода обратного вызова

Выполнение функционального тестирования модели просмотра, я могу высмеять прокси-сервер службы, чтобы обеспечить, чтобы методы вызывались на прокси-сервере, но как я могу гарантировать, что метод обратного вызова также вызван?

С RhinoMocks Я могу проверить, что события обрабатываются событиями и событиями события на издеваемом объекте, но как я могу проверить обратные вызовы?

ViewModel:

public class MyViewModel 
{ 
    public void GetDataAsync() 
    { 
     // Use DI framework to get the object 
     IMyServiceClient myServiceClient = IoC.Resolve<IMyServiceClient>(); 
     myServiceClient.GetData(GetDataAsyncCallback); 
    } 

    private void GetDataAsyncCallback(Entity entity, ServiceError error) 
    { 
     // do something here... 
    } 

} 

ServiceProxy:

public class MyService : ClientBase<IMyService>, IMyServiceClient 
{ 
    // Constructor 
    public NertiAdminServiceClient(string endpointConfigurationName, string remoteAddress) 
     : 
      base(endpointConfigurationName, remoteAddress) 
    { 
    } 

    // IMyServiceClient member. 
    public void GetData(Action<Entity, ServiceError> callback) 
    { 
     Channel.BeginGetData(EndGetData, callback); 
    } 

    private void EndGetData(IAsyncResult result) 
    { 
     Action<Entity, ServiceError> callback = 
      result.AsyncState as Action<Entity, ServiceError>; 

     ServiceError error; 
     Entity results = Channel.EndGetData(out error, result); 

     if (callback != null) 
      callback(results, error); 
    } 
} 

Благодаря

ответ

1

поиграли с этим немного, и я думаю, что, возможно, есть то, что вы ищете. Во-первых, я буду показывать MSTest код, который я сделал, чтобы проверить это:

[TestClass] 
public class UnitTest3 
{ 
    private delegate void MakeCallbackDelegate(Action<Entity, ServiceError> callback); 

    [TestMethod] 
    public void CallbackIntoViewModel() 
    { 
     var service = MockRepository.GenerateStub<IMyServiceClient>(); 
     var model = new MyViewModel(service); 

     service.Stub(s => s.GetData(null)).Do(
      new MakeCallbackDelegate(c => model.GetDataCallback(new Entity(), new ServiceError()))); 
     model.GetDataAsync(null); 
    } 
} 

public class MyViewModel 
{ 
    private readonly IMyServiceClient client; 

    public MyViewModel(IMyServiceClient client) 
    { 
     this.client = client; 
    } 

    public virtual void GetDataAsync(Action<Entity, ServiceError> callback) 
    { 
     this.client.GetData(callback); 
    } 

    internal void GetDataCallback(Entity entity, ServiceError serviceError) 
    { 

    } 
} 

public interface IMyServiceClient 
{ 
    void GetData(Action<Entity, ServiceError> callback); 
} 

public class Entity 
{ 
} 

public class ServiceError 
{ 
} 

Вы заметите несколько вещей:

  1. Я сделал ваш обратный вызов внутренней. Вам нужно будет использовать атрибут InternalsVisisbleTo(), чтобы ваша сборка ViewModel предоставляла внутренности вашим модульным тестам (я не сумасшедший об этом, но это происходит в редких случаях, подобных этому).

  2. Я использую Rhino.Mocks «Do» для выполнения обратного вызова всякий раз, когда вызывается GetData. Он не использует обратный вызов, но это действительно больше интеграционный тест. Я предполагаю, что у вас есть модульный тест ViewModel, чтобы убедиться, что реальный обратный вызов, переданный в GetData, выполняется в соответствующее время.

  3. Очевидно, что вы захотите создать объекты Entity и ServiceError для mock/stub вместо того, чтобы просто обновляться, как я.

+0

мог бы рассказать, как я могу сделать внутренний метод видимым для проекта модульного тестирования. спасибо – joblot

+0

Я разработал, как сделать внутренний метод видимым. Не могли бы вы объяснить, что делает действительно, и почему мы создали Стад для этой услуги. спасибо – joblot

+0

Это всего лишь единичный тест для вашего ViewModel. Таким образом, все внешние зависимости издеваются/обрезаются. Метод «Do» сообщает Rhino.Mocks выполнять конкретную часть кода всякий раз, когда вызывается метод. Я использовал «Do», чтобы ваш ViewModel смог вызвать «GetDataAsync», а также получить обратный вызов - все во время тестирования. Проверка того, выполняет ли служба обратные вызовы как часть модульного теста класса Service. – PatrickSteele