9

任何时候使用 Moq 编写单元测试时,我调用Elmah.ErrorSignal.FromCurrentContext它都会失败,并出现空引用异常。我能够模拟ControllerContext并且我只想使用这样的错误日志命令..

Elmah.ErrorSignal.FromContext(ControllerContext.HttpContext).Raise(e);

但不幸的ControllerContext.HttpContext是,它是类型HttpContextBase,不适用于这种错误记录方法。

有没有更好的方法来直接调用 Elmah 错误记录?不幸的是,该Application.HttpContext对象不能被模拟(下面的例子)或者也可以达到目的。

模拟ApplicationApplication.HttpContext

ctrlCtx.SetupGet(x => x.HttpContext.ApplicationInstance)
           .Returns(new Mock<HttpApplication>().Object);
ctrlCtx.SetupGet(x => x.HttpContext.ApplicationInstance.Context)
           .Returns(new Mock<HttpContext>().Object);

产生的错误:

非虚拟(在 VB 中可覆盖)成员上的设置无效

4

2 回答 2

14

虽然您不能模拟 HttpContext,但您可以在测试中设置 HttpContext.Current。

var req = new HttpRequest(string.Empty, "https://www.domain.tld", null);
var res = new HttpResponse(null);
HttpContext.Current = new HttpContext(req, res);

不过,我不确定 Elmah 使用了上下文的哪些部分。

第 3 方编辑:
ELMAH 还需要 System.Web.HttpContext.Current.ApplicationInstance

Dim req As System.Web.HttpRequest = New System.Web.HttpRequest(String.Empty, "https://www.domain.tld", Nothing)
Dim res As System.Web.HttpResponse = New System.Web.HttpResponse(Nothing)
System.Web.HttpContext.Current = New System.Web.HttpContext(req, res)

System.Web.HttpContext.Current.ApplicationInstance = New System.Web.HttpApplication()

否则会抛出异常,因为应用程序名称为 NULL。

进一步编辑:
这是 C# 中的最终代码:

var req = new HttpRequest(string.Empty, "https://www.domain.tld", null);
var res = new HttpResponse(null);
HttpContext.Current = new HttpContext(req, res) 
     {ApplicationInstance = new HttpApplication()};
于 2012-05-18T21:05:15.487 回答
7

在 Elmah 中以不同方式记录错误的一件事是使用:

Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(e)); 

尽管这不会从单元测试中记录错误,但它至少会在单元测试中完全跳过记录,并且在正常情况下仍会记录错误。

于 2012-05-21T13:30:31.003 回答