2012-02-29 35 views
1

对于单元测试,我使用moq来模拟连接到HttpContextBase的HttpServerUtilityBase。这样当被测试的函数可以调用context.server(ASP.Net)时。Moq context.server.transfer

但是,当测试方法执行context.server.transfer时,如果在应用程序中完成此操作,则会导致函数(在httphandler中调用)停止执行。在我的moq'd版本中,执行“传输”调用,然后继续执行。

为了解决这个问题,我在转移后放置了返回语句,但这些语句被stylecop正确识别为冗余。

我可以设置我的模拟强制调用方法返回?

例如,如果我们要测试的方法是这样的:

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的执行,除非我把在返回后传中测试将执行过去“等等......”块。

+2

你可以发布一些上下文的代码? – 2012-03-01 00:03:44

+0

为上下文添加示例 – 2012-03-02 15:47:21

回答

1

这是非常棘手的,这就是为什么它通常不建议嘲笑你不拥有的对象。一种解决方案是抛出一个异常(我认为它是如何在ASP.NET代码中完成的)。有关“重新定向后停止执行”部分下的示例,请参见此link

因此,像:

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

然后赶上与NUnit的的Assert.Throws。

+0

这是一个很好的答案。起初看起来有些黑客要抛出一个异常来停止执行,但链接解释说,这是框架在传输过程中所做的事情 – 2012-03-02 20:00:23