与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)));
}