Domanda

Ho una classe proxy di servizio che fa chiamata asyn al funzionamento del servizio. Io uso un metodo di callback per passare i risultati di nuovo al mio modello di vista.

In questo test funzionali di vista del modello, posso prendere in giro proxy del servizio al fine di garantire metodi sono chiamati sul proxy, ma come posso garantire che il metodo di callback si chiama così?

Con RhinoMocks posso provare che gli eventi vengono gestiti e gli eventi alzare evento sull'oggetto deriso, ma come faccio a testare le richiamate?

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

Grazie

È stato utile?

Soluzione

giocato con questo un po 'e penso che io possa avere quello che stai cercando. In primo luogo, io visualizzare il codice MSTest ho fatto per verificare questo:

[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
{
}

Avrete notato un paio di cose:

  1. Ho fatto il callback interna. Avrete bisogno di utilizzare l'attributo InternalsVisisbleTo () in modo che il ViewModel espone assemblaggio interni per il test di unità (io non sono pazzo di questo, ma succede in rari casi come questo).

  2. Io uso Rhino.Mocks "Do" per eseguire la richiamata ogni volta che la si chiama GetData. Non è usando la richiamata in dotazione, ma questo è davvero più di un test di integrazione. Presumo che hai un test di unità ViewModel per assicurarsi che il vero callback passato a GetData viene eseguito al momento opportuno.

  3. Ovviamente, ti consigliamo di creare finto / stub Entità e ServiceError oggetti invece di new'ing up come ho fatto io.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top