Тестирование образцов обратного вызова Rhinomocks

StackOverflow https://stackoverflow.com/questions/2925861

  •  05-10-2019
  •  | 
  •  

Вопрос

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

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

С помощью 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...
    }

}

СервисПрокси:

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

Спасибо

Это было полезно?

Решение

Играл с этим немного, и я думаю, что у меня может быть то, что вы ищете. Во-первых, я покажу код 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. Я сделал ваш обратный вызов внутренним вызовом. Вам нужно будет использовать атрибут internalsVisbleto (), чтобы ваша сборка ViewModel предоставляла внутренние тесты на ваши устройства (я не без ума от этого, но это происходит в таких редких случаях).

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top