[英]How to Mock HttpContextBase correctly so my unit tests are working
Given the following function: 赋予以下功能:
public static void Write(HttpContextBase contextBase, IUnitOfWork unitOfWork, LogLevel level, string title, string message, params AdditionalProperty[] properties)
{
// Some variables that are set for writing the logs.
// - client: When the HttpContext is null, 'N.A.' is used, otherwise the I.P. address of the requesting computer.
// - userIdentifier: When the HttpContext exists and a value is stored in the cookie, the value of the cookie, otherwise an empty guid.
// - requestIdentifier: When the context is existing and a request have been made on a controller, a unique value identifying this request, otherwise an empty guid.
string client = (contextBase.ApplicationInstance == null || contextBase.ApplicationInstance.Context.CurrentHandler == null) ? "N.A." : HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
string userIdentifier = (contextBase.ApplicationInstance != null && contextBase.ApplicationInstance.Context != null && contextBase.ApplicationInstance.Context.CurrentHandler != null && CookieManager.Exists("UserIdentifier")) ? CookieManager.Read("UserIdentifier", Guid.NewGuid().ToString().ToUpper()) : Guid.Empty.ToString();
string requestIdentifier = (contextBase.ApplicationInstance != null && contextBase.ApplicationInstance.Context != null && contextBase.ApplicationInstance.Context.Cache != null && HttpContext.Current.Cache["RequestIdentifier"] != null) ? HttpContext.Current.Cache["RequestIdentifier"].ToString() : Guid.Empty.ToString();
// Additional code for processing is done here.
}
I'm using a HttpContextBase and an interface for a Unit Of Work, since I know it's easier to unit test than. 我正在为工作单元使用HttpContextBase和接口,因为我知道单元测试比工作起来容易。
Now I'm using Moq to using Mocking functionality in my unit test and I'm struggling with it. 现在,我在单元测试中使用Moq来使用Mocking功能,但我为此感到吃力。
Let's see the variable cliënt: 让我们看一下变量cliënt:
string client = (contextBase.ApplicationInstance == null || contextBase.ApplicationInstance.Context.CurrentHandler == null) ? "N.A." : HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
I would like to know how to setup my Unit Test(s) by mocking the necessary objects. 我想知道如何通过模拟必要的对象来设置我的单元测试。
Here's my current unit test: 这是我当前的单元测试:
var context = new Mock<HttpContextBase>();
var httpApplicationMock = new Mock<HttpApplication>();
httpApplicationMock.SetupGet(x => x.Context).Returns(context.Object); --> FAILS
context.SetupGet(c => c.ApplicationInstance).Returns(httpApplicationMock.Object);
The setup of the httpApplicationMock is failing because context.Object is not a valid parameter but I need to pass in a HttpContext. httpApplicationMock的设置失败,因为context.Object不是有效的参数,但是我需要传递HttpContext。
Can someone give me a little, gentle push in the right direction? 有人可以给我一点点正确方向的推动力吗?
This line fails because Context
returns HttpContext
type, not HttpContextBase
. 该行失败,因为
Context
返回HttpContext
类型,而不是HttpContextBase
。
httpApplicationMock.SetupGet(x => x.Context).Returns(context.Object);
Creating context
as Mock<HttpContext>
instance won't help either because it's a sealed class and Moq can't mock sealed classes. 创建
context
作为Mock<HttpContext>
实例也无济于事,因为它是一个密封的类,而Moq无法模拟密封的类。
You can hide implementation details concerning HttpContext behind an interface. 您可以在接口后面隐藏有关HttpContext的实现细节。 Here's blog post that shows you an example: http://volaresystems.com/Blog/post/2010/08/19/Dont-mock-HttpContext
这是为您显示示例的博客文章: http : //volaresystems.com/Blog/post/2010/08/19/Dont-mock-HttpContext
After some further tests I've realized what it wrong. 经过一些进一步的测试,我意识到了问题所在。
First of all, and quite important, I'm using MSTest. 首先,非常重要,我正在使用MSTest。 So the problem does not rely on repository being created in the constructor because for each test that is runt through MSTest, the constructor is executed.
因此,问题不依赖于在构造函数中创建的存储库,因为对于通过MSTest运行的每个测试,都将执行构造函数。 So that's eliminated.
这样就消除了。
After some further inspection, I've realised that, to retrieve the settings from the settingsrepository, I use a class which is instantiated as a Singleton, and that was the problem. 经过进一步检查,我意识到,要从设置存储库检索设置,我使用了一个实例化为Singleton的类,这就是问题所在。
When I run my first file with unit test with a specified setting, all went fine since the setting still needed to be created. 当我使用具有指定设置的单元测试运行我的第一个文件时,由于仍需要创建该设置,因此一切正常。
But in my second file, I use another settings, but since the manager which is responsible for getting the settings is a Singleton, the new settings were not retrieved and instead the settings from the previous one were used. 但是在第二个文件中,我使用了另一个设置,但是由于负责获取设置的管理器是Singleton,因此未检索到新设置,而是使用了前一个设置。
That caused the issue. 这引起了问题。
Anyway, thanks to the persons who have tried to helped me out on this situation. 无论如何,要感谢那些试图帮助我解决这种情况的人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.