2012-02-29 7 views
1

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

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

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

Могу ли я настроить свой макет, чтобы заставить метод вызова вернуться?

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

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 издевались, передача не остановит выполнение ProcessRequest, и если я не положил в возвращении после переноса тест будет выполняться мимо «ETC ...» блок.

+2

Можете ли вы опубликовать некоторый код для небольшого контекста? –

+0

Добавлены примеры для контекста –

ответ

1

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

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

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

Тогда поймать, что с Assert.Throws NUnit в.

+0

Это хороший ответ. Поначалу казалось немного взломать исключение, чтобы остановить выполнение, но ссылка объясняет, что это то, что делает каркас на переносе –