两次对同一对象进行存根时,RhinoMocks会失败吗?

时间:2016-09-27 12:16:50

标签: c# mocking rhino-mocks

我认为代码会比我糟糕的标题更好地解释这个问题。

_httpContextBaseHttpContextBase,但我认为这不重要。 _httpCookiecollection只是HttpCookieCollection

//Works fine
_httpContextBase.Stub(c => c.Response.Cookies).Return(_httpCookieCollection);

//Fails after attempting to stub the second line. "Object reference not set to an instance of an object". First line passes fine.
_httpContextBase.Stub(c => c.Response.Cookies).Return(_httpCookieCollection);
_httpContextBase.Stub(c => c.Request.Cookies).Return(_httpCookieCollection);

//Work around
var responseBaseMock = MockRepository.GenerateMock<HttpResponseBase>();
responseBaseMock.Stub(r => r.Cookies).Return(_httpCookieCollection);
_httpContextBase.Stub(c => c.Response).Return(responseBaseMock);

var requestBaseMock = MockRepository.GenerateMock<HttpRequestBase>();
requestBaseMock.Stub(r => r.Cookies).Return(_httpCookieCollection);
_httpContextBase.Stub(c => c.Request).Return(requestBaseMock);

想象一下,上面的测试都是各自的方法。每条评论都解释了当下面的代码运行时会发生什么。

第一项有效,第二项失败,第三项是我的工作。我想知道的是为什么第二项失败,因为我似乎无法弄明白。


第2项的堆栈跟踪(即使第1行和第2行被反转,也是相同的堆栈跟踪)

System.NullReferenceException : Object reference not set to an instance of an object.
   at Api.Tests.Client.CookieTests.<>c.<Test>b__12_1(HttpContextBase c) in Api.Tests\Client\CookieTests.cs:line 113
   at Rhino.Mocks.RhinoMocksExtensions.Expect[T,R](T mock, Function`2 action)
   at Rhino.Mocks.RhinoMocksExtensions.Stub[T,R](T mock, Function`2 action)
   at .Api.Tests.Client.CookieTests.Test() in .Api.Tests\Client\CookieTests.cs:line 113

2 个答案:

答案 0 :(得分:1)

我知道我参加聚会有点晚了,这对申请者而言可能不再重要,但是我仍然会为Rhino Mocks的新手提供答案。

使用Rhino Mocks进行模拟时,如果多次调用该方法,则需要将.Repeat.Once()附加到每个不同的存根上。 (.Once()可以替换为使用.Twice().Times(x)获得新响应之前需要使用该响应的适当次数,其中x替换为您需要拨打电话的次数。

答案 1 :(得分:0)

我还没有尝试过你的代码,所以我可能不对。但它可能是_httpContextBase.Request为null。如果是这种情况,以及NullReferenceException的原因,那么看起来_httpContextBase.Response不是null,因为它没有相同的问题。

我不知道在您的测试中设置了该对象,但这可能是值得关注的。另外,你有相反的尝试吗?我猜它与.Request有关,而不是它是第二个存根。

我知道你还没有要求它,但我也建议采用一种不同的方法,我发现它可以用来模拟像HttpContext这样复杂的东西。编写一个抽象接口,公开您要使用的部分(例如ResponseCookies和RequestCookies)。您对该接口的实现可以直接使用HttpContext成员,但您的其他类不再依赖,并且您有一个非常简单的模拟或存根接口。