如何用 Nunit 和 RhinoMocks 模拟 HttpContext.Current.GetOwinContext()?

How to mock HttpContext.Current.GetOwinContext() with Nunit and RhinoMocks?

相比,我不得不将正在测试的方法更改为

public override void OnActionExecuting(HttpActionContext actionContext)
{
    HttpContext.Current.GetOwinContext().Set("RequestGUID", NewId.NextGuid());
    base.OnActionExecuting(actionContext);
}

现在我需要弄清楚如何模拟 HttpContext.Current.GetOwinContext(), 所以我可以为 Set() 方法编写一个存根,或者通常能够测试这一特定行。我怎样才能做到这一点?

我已经阅读了this article,但是对于你的情况,我认为这样做是一种矫枉过正..

由于GetOwinContext() return一个接口你所要做的就是将这个调用与方法分开,这样做有两个问题:

  1. 正在测试的方法(OnActionExecuting() 属于属性 class。
  2. GetOwinContext() 是一个静态方法。

我可以为您提供的 2 个最佳解决方案是:

  1. 使用 MsFakes、Typemock Isolator 等代码挥舞工具,而不是 RhinoMocks 等基于代理的工具。
  2. GetOwinContext()提取为虚方法,然后使用PartialMock技术(此技术通常用于抽象classes):

假设 MyCustonAttributte 是您的属性:

public class MyCustonAttributte : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        GetOwinContext().Set("RequestGUID", Guid.NewGuid());
        base.OnActionExecuting(actionContext);
    }

    public virtual IOwinContext GetOwinContext()
    {
        return HttpContext.Current.GetOwinContext();
    }
}

那么您的 UT 将是:

[Test]
public void New_GUID_should_be_added_when_OnActionExecuting_is_executing()
{
    //arrange section:
    const string REQUEST_GUID_FIELD_NAME = "RequestGUID";
    var owinContext = MockRepository.GenerateStub<IOwinContext>();

    var target = MockRepository.GeneratePartialMock<MyCustonAttributte>();

    target.Stub(x => x.GetOwinContext())
        .Return(owinContext);

    //act:
    target.OnActionExecuting(new HttpActionContext());

    //assert section:
    owinContext.AssertWasCalled(x => x.Set(Arg<string>.Is.Equal(REQUEST_GUID_FIELD_NAME),
        Arg<Guid>.Is.NotEqual(Guid.Empty)));
}