2012-02-29 37 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