C# 如何正确模拟HttpContextBase以使我的单元测试正常工作

C# 如何正确模拟HttpContextBase以使我的单元测试正常工作,c#,unit-testing,mocking,moq,C#,Unit Testing,Mocking,Moq,鉴于以下功能: 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. // - clien

鉴于以下功能:

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.
}
我正在使用一个HttpContextBase和一个工作单元接口,因为我知道进行单元测试比测试更容易

现在我在单元测试中使用Moq来使用mock功能,我正在努力解决这个问题

让我们看看变量cliënt:

string client = (contextBase.ApplicationInstance == null || contextBase.ApplicationInstance.Context.CurrentHandler == null) ? "N.A." : HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
我想知道如何通过模拟必要的对象来设置单元测试

下面是我当前的单元测试:

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);
var context=newmock();
var httpApplicationMock=new Mock();
httpApplicationMock.SetupGet(x=>x.Context).返回(Context.Object);-->失败
SetupGet(c=>c.ApplicationInstance).Returns(httpApplicationMock.Object);
httpApplicationMock的设置失败,因为context.Object不是有效参数,但我需要传入HttpContext


有人能帮我朝正确的方向轻轻推一下吗?

此行失败,因为
Context
返回
HttpContext
类型,而不是
HttpContextBase

httpApplicationMock.SetupGet(x => x.Context).Returns(context.Object);
创建
context
作为
Mock
实例也不会有帮助,因为它是一个密封类,Moq不能模拟密封类


您可以在接口后面隐藏有关HttpContext的实现细节。这里有一篇博客文章向您展示了一个例子:

经过进一步的测试,我意识到它错在哪里了

首先,非常重要的是,我正在使用MSTest。因此,问题不依赖于在构造函数中创建的存储库,因为对于通过MSTest运行的每个测试,都会执行构造函数。所以这就被淘汰了

经过进一步的检查,我意识到,为了从settingsrepository检索设置,我使用了一个实例化为Singleton的类,这就是问题所在

当我用指定的设置运行带有单元测试的第一个文件时,一切都很顺利,因为仍然需要创建该设置

但是在我的第二个文件中,我使用了另一个设置,但是由于负责获取设置的管理器是单例的,因此没有检索到新的设置,而是使用了前一个设置中的设置

这引发了问题


无论如何,感谢那些在这种情况下帮助过我的人。

这意味着我需要重写我的“LogManager”,因为您希望我向它传递一个接口(可能通过使用依赖注入)。对吗?@Complexity我看不到您的LogManager类,但通过注入传递依赖项通常是个好主意。不过我不会称之为重写。好吧,我已经解决了这个问题,并告诉你它是什么。在我的LogManager类中,我研究的是HttpContext和单元测试中不可用的东西。因此,我将一个参数传递给我的logManager,作为一个接口,该接口具有来自HttpContext的属性。在我的Web应用程序中,我有一个接口的impmlement,其中所有属性都是基于HttpContext填充的,而在我的单元测试中,我有一个只返回字符串值的接口模拟。你能向我证实这是正确的工作方式吗?@复杂性我也会这样做,但不能说这是正确的还是错误的:)我理解。一个问题仍然存在。我无法使用HttpContext对具有属性的类进行单元测试,以查看if语句是否正确,但这不是真正的问题。我认为这个案子已经结束了。感谢您的宝贵帮助:-)