Мокинг асинхронных вызовов в Silverlight WCF Proxy с использованием Moq

У меня есть типичное приложение Silverlight со службой WCF, и я использую slsvcutil.exe для создания стандартного клиентского прокси-сервера для связи с веб-службой. Я пытаюсь писать модульные тесты, и я но когда я пытаюсь запустить любой тест с использованием макета и установить точки останова, событие TestCompleted никогда не возникает, когда я вызываю TestAsync ().

Есть ли что-нибудь очевидное, чего мне не хватает, или какие-нибудь лучшие идеи по поводу имитации этих типов прокси-серверов асинхронных служб в Silverlight?

Спасибо!

РЕДАКТИРОВАТЬ:

Чтобы было более понятно, что я на самом деле пытаюсь проверить - это созданный мной вспомогательный класс, который принимает экземпляр IServiceProxy и предоставляет более чистый сервисный интерфейс для моей модели ViewModel, который можно использовать, принимая параметры обратного вызова Action вместо того, чтобы иметь дело с обратным вызовом события в моей ViewModel. Я понимаю, как я могу издеваться над этим, чтобы напрямую протестировать мою ViewModel, но я подумал, что было бы неплохо сначала протестировать вспомогательный класс сам по себе.

Вот пример того, о чем я говорю:

public class HelperClient : IServiceHelper
{
    private IServiceProxy proxy;

    public HelperClient(IServiceProxy proxy)
    {
        this.proxy = proxy;

        // register to handle all async callback events
        this.proxy.TestCompleted += new EventHandler<TestCompletedEventArgs>(TestCompleted);
    }

    public void Test(TestRequest request, Action<TestResponse, Exception> response)
    {
        this.proxy.TestAsync(request, response);
    }

    private void TestCompleted(object sender, TestCompletedEventArgs e)
    {
        var response = e.UserState as Action<TestResponse, Exception>;

        if (response != null)
        {
            var ex = GetServiceException(e);

            if (ex == null)
            {
                response(e.Result, null);
            }
            else
            {
                response(null, ex);
            }
        }
    }
}

Итак, в моем тесте я фактически имитирую ISerivceProxy, передаю его и просто пытаюсь протестировать вызов службы, чтобы убедиться, что оболочка, вызывающая действие правильно:

[TestMethod]
[Asynchronous]
public void Test_Returns_Expected()
{
    var mockProxy = new Mock<IServiceProxy>();
    var helper = new HelperClient(mockProxy.Object);
    bool expectedResult = true;
    var result = new TestResponse() { Value = expectedResult };

    this.mockProxy.Setup(
        p => p.TestAsync(It.IsAny<TestRequest>()))
        .Raises(p => p.TestCompleted += null, new TestCompletedEventArgs(new object[] { result }, null, false, null));

    helper.Test(new TestRequest(), (response, ex) =>
    {
        Assert.AreEqual(expectedResult, response.Value);
        EnqueueTestComplete();
    });
}

Проблема в том, что имитируемый прокси-объект никогда не вызывает событие TestCompleted, поэтому мое ответное действие никогда не вызывается для завершения теста (даже если тест кажется завершенным успешно, Assert никогда не запускается). Извините за такой длинный пост, просто пытаюсь показать вам как можно больше кода.

РЕДАКТИРОВАТЬ 2

Добавлен [Асинхронный] и вызов EnqueueTestComplete () , который я понял, что мне может потребоваться заставить тест ждать возникновения события. Это не очень помогло, событие по-прежнему не возникает, поэтому тест просто зависает и никогда не завершается.

РЕДАКТИРОВАТЬ 3

Ответ Алиостада был правильным: подпись моего ожидания настройки не соответствовала фактической подписи Test (), что позволило мне передать действие ответа в качестве второго параметра. Глупая ошибка, но именно это не позволяло Moq вызвать событие Completed. Я также забыл передать Action как объект userState в TestCompletedEventArgs, чтобы он действительно вызывался при возникновении события Completed. Кроме того, [Асинхронный] и EnqueueTestCompleted , похоже, не нужны в этом случае.

Здесь обновленный тестовый код для всех, кто интересуется:

[TestMethod]
public void Test_Returns_Expected()
{
    var mockProxy = new Mock<IServiceProxy>();
    var helper = new HelperClient(mockProxy.Object);
    bool expectedResult = true;
    var result = new TestResponse() { Value = expectedResult };

    Action<TestResponse, Exception> responseAction = (response, ex) =>
    {
        Assert.AreEqual(expectedResult, response.Value);
    };

    this.mockProxy.Setup(
        p => p.TestAsync(It.IsAny<TestRequest>(), It.IsAny<Action<TestResponse, Exception>>()))
        .Raises(p => p.TestCompleted += null, new TestCompletedEventArgs(new object[] { result }, null, false, responseAction));

    helper.Test(new TestRequest(), responseAction);
}
7
задан Dan Auclair 4 October 2010 в 16:16
поделиться