Moq context.server.transfer - PullRequest
       5

Moq context.server.transfer

1 голос
/ 29 февраля 2012

Для модульного теста я использую moq для макета HttpServerUtilityBase, присоединенного к HttpContextBase. Это связано с тем, что когда тестируемая функция может вызывать context.server (ASP.Net).

Однако, когда тестируемый метод выполняет context.server.transfer, при выполнении в приложении это приводит к остановке выполнения функции (вызываемой в httphandler). В моей версии moq'd "передача" вызов выполняется, а затем выполнение продолжается.

Чтобы бороться с этим, я поместил операторы return после передачи, но они правильно определены как избыточные с помощью stylecop.

Могу ли я настроить свой Mock для принудительного возврата вызывающего метода?

Например, если мы тестируем такой метод:

public void ProcessRequest(HttpContextBase context, string username, Logger logger)
{
    if (string.isNullOrEmpty(username))
    {
        logger.Warn("Blah Blah invalid username");
        context.Server.Transfer("~/ErrorPage.aspx");
    }
    ETC...
}

Следующий код правильно проверит правильность действий с неверным именем пользователя.

[TestMethod]
public void ProcessRequestTest()
{
    // Set up my mocks
    var logger = new Mock<ILogger>();
    logger.Setup(l => l.Warn(It.IsAny<string>());
    var context = new Mock<HttpContextBase>();
    var server = new Mock<HttpServerUtilityBase>();
    context.Setup(c => c.Server).Returns(server.Object);

    // Try an invalid call
    var rh = new MyRequestHandler();
    rh.ProcessRequest(context.Object, string.empty, logger.Object);

    // Check that the message was logged and the transfer was made
    logger.Verify(l => l.Warn(It.IsRegex("invalid username"));
    server.Verify(s => s.Transfer(It.IsAny<string>()));
}

Однако из-за того, что context.Server является поддельным, Transfer не остановит выполнение ProcessRequest, и пока я не введу возврат после передачи, тест будет выполнен после блока «ETC ...».

1 Ответ

1 голос
/ 02 марта 2012

Это довольно сложно и поэтому обычно не рекомендуется издеваться над объектами, которые вам не принадлежат.Одним из решений было бы создать исключение (которое, я думаю, заключается в том, как это делается в коде ASP.NET).Посмотрите эту ссылку для примера в разделе «Остановка выполнения после перенаправления».

Так что-то вроде:

server.Setup(s => s.Transfer(It.IsAny<string>()).Throws<TransferException>();

Затем поймайте это с помощью Assert.Throws NUnit..

...