my last question on Mocking the HttpContext相比,我不得不将测试方法更改为

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


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

最佳答案

我已经读过this article,但是对于您而言,我认为做这样的事情会太过分了。

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


被测方法(OnActionExecuting()由属性类拥有。
GetOwinContext()是静态方法。


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


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


假设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)));
}

08-19 00:34