C# 单元测试OpenIdRelyingParty
如果这是一个重复的问题,我很抱歉(我没有发现类似的问题)。 我正在尝试构建OpenId身份验证服务并对其进行单元测试,目前我有以下设置:C# 单元测试OpenIdRelyingParty,c#,asp.net-mvc-3,dependency-injection,openid,dotnetopenauth,C#,Asp.net Mvc 3,Dependency Injection,Openid,Dotnetopenauth,如果这是一个重复的问题,我很抱歉(我没有发现类似的问题)。 我正在尝试构建OpenId身份验证服务并对其进行单元测试,目前我有以下设置: public class OpenIdAuthenticationService : IAuthenticationService { private IConfigurationService _configService; private OpenIdRelyingParty _openIdRelyingParty;
public class OpenIdAuthenticationService : IAuthenticationService
{
private IConfigurationService _configService;
private OpenIdRelyingParty _openIdRelyingParty;
public OpenIdAuthenticationService(IConfigurationService configService)
{
_configService = configService;
_openIdRelyingParty = new OpenIdRelyingParty();
}
}
显然OpenIdRelyingParty需要访问HttpContext,有没有办法模拟OpenIdRelyingParty并向其注入服务?或者模拟HttpContext并以某种方式将其提供给OpenIdRelyingParty?既然您已经在这样做了,我会像使用配置服务一样将
OpenIdRelyingParty
注入到构造函数中
除此之外,您可以在单元测试中模拟HttpContextHttpContext.Current
有一个setter,因此将其设置为mock/stubHttpContextBase
。下面是一个使用NUnit的示例:
[TearDown]
public void CleanUp()
{
HttpContext.Current = null;
}
[Test]
public void FakeHttpContext()
{
var context = Substitute.For<HttpContextBase>();
var request = Substitute.For<HttpRequestBase>();
context.Request.Returns(request);
//Do any more arragement that you need.
//Act
//Assert
}
[拆卸]
公共空间清理()
{
HttpContext.Current=null;
}
[测试]
public void FakeHttpContext()
{
var context=Substitute.For();
var request=Substitute.For();
context.Request.Returns(请求);
//做任何你需要的安排。
//表演
//断言
}
但对我来说,这可能有点代码味道。它是测试依赖关系的依赖关系(或者说不管兔子洞到底有多远)。不过,当重构不是一个选项时,它很有用。既然您已经在做了,我会像使用配置服务一样将
OpenIdRelyingParty
注入到构造函数中
除此之外,您可以在单元测试中模拟HttpContextHttpContext.Current
有一个setter,因此将其设置为mock/stubHttpContextBase
。下面是一个使用NUnit的示例:
[TearDown]
public void CleanUp()
{
HttpContext.Current = null;
}
[Test]
public void FakeHttpContext()
{
var context = Substitute.For<HttpContextBase>();
var request = Substitute.For<HttpRequestBase>();
context.Request.Returns(request);
//Do any more arragement that you need.
//Act
//Assert
}
[拆卸]
公共空间清理()
{
HttpContext.Current=null;
}
[测试]
public void FakeHttpContext()
{
var context=Substitute.For();
var request=Substitute.For();
context.Request.Returns(请求);
//做任何你需要的安排。
//表演
//断言
}
但对我来说,这可能有点代码味道。它是测试依赖关系的依赖关系(或者说不管兔子洞到底有多远)。当重构不是一个选项时,它很有用。要模拟OpenIdRelyingParty的HttpContext,您应该修改该类的代码。甚至你也会浪费一些时间去嘲笑它,因为它是一个密封的类(但你也可以使用它) 我认为最好为OpenIdRelyingParty制作一个包装器或适配器。比如:
public class OpenIdRelyingPartyWrapped
{
private OpenIdRelyingParty openIdRelyingPartyTarget;
....
public virtual IAuthenticationRequest CreateRequest(string text)
{
return this.openIdRelyingPartyTarget.CreateRequest(text);
}
...
}
然后,您可以根据需要模拟它。要模拟OpenIdRelyingParty的HttpContext,您应该修改该类的代码。甚至你也会浪费一些时间去嘲笑它,因为它是一个密封的类(但你也可以使用它) 我认为最好为OpenIdRelyingParty制作一个包装器或适配器。比如:
public class OpenIdRelyingPartyWrapped
{
private OpenIdRelyingParty openIdRelyingPartyTarget;
....
public virtual IAuthenticationRequest CreateRequest(string text)
{
return this.openIdRelyingPartyTarget.CreateRequest(text);
}
...
}
然后,您可以根据需要对其进行模拟。
OpenIdRelyingParty
可以通过使用方法重载在单元测试中使用,方法重载接受可完全模拟的HttpRequestBase
。只有不将其作为参数的方法才需要一个HttpContext。通过使用接受HttpRequestBase
的方法重载,可以在单元测试中使用Current
OpenIdRelyingParty
,这是完全可以模拟的。只有不将其作为参数的方法才需要HttpContext.Current
谢谢,我可以将OpenIdRelyingParty取出并通过构造函数注入,但是我如何在单元测试中初始化它?它需要HttpContext,但无法提供它?@2Dim1通过构造函数注入它的接口,然后模拟接口。这样,就不会使用“真正的”实现,也不会影响HttpContext。我感谢您的帮助。老实说,我已经尝试过了,但是OpenIdRelyingParty似乎不是DotNetOpenAuth中IOpenIdRelyingParty的实现?除非我遗漏了什么?谢谢,我可以取出OpenIdRelyingParty并通过构造函数注入它,但是我如何在单元测试中初始化它?它需要HttpContext,但无法提供它?@2Dim1通过构造函数注入它的接口,然后模拟接口。这样,就不会使用“真正的”实现,也不会影响HttpContext。我感谢您的帮助。老实说,我已经尝试过了,但是OpenIdRelyingParty似乎不是DotNetOpenAuth中IOpenIdRelyingParty的实现?除非我遗漏了什么?谢谢,我喜欢这种方法,但在这种情况下,我如何初始化OpenIdRelyingParty?我应该从包装器中初始化它并注入它吗?或者我应该检查它是否为null并定义一个默认值?或者我遗漏了什么?这取决于创建实例的策略如果您使用的是IOC,您应该保留它,那么注入将通过构造函数或属性进行。如果您没有使用IOC,您可以在OpenIDrelyingPartyRapped的构造函数中创建实例。对于或您的单元测试,您应该创建一个从OpenIDrelyingPartyRapped继承的模拟类,并覆盖您想要模拟的方法。谢谢,我喜欢这种方法,但是在这种情况下,我应该如何初始化OpenIdRelyingParty?我应该从包装器中初始化它并注入它吗?或者我应该检查它是否为null并定义一个默认值?或者我遗漏了什么?这取决于创建实例的策略如果您使用的是IOC,您应该保留它,那么注入将通过构造函数或属性进行。如果您没有使用IOC,您可以在OpenIDrelyingPartyRapped的构造函数中创建实例。对于或您的单元测试,您应该创建一个从OpenIDrelyingPartyRapped继承的模拟类,并重写要模拟的方法。