0

如果这是一个重复的问题,我深表歉意(我没有找到类似的问题)。我正在尝试构建一个 OpenId 身份验证服务并对其进行单元测试,目前我有以下设置:

public class OpenIdAuthenticationService : IAuthenticationService
{
    private IConfigurationService   _configService;
    private OpenIdRelyingParty      _openIdRelyingParty;

    public OpenIdAuthenticationService(IConfigurationService configService)
    {
        _configService      = configService;
        _openIdRelyingParty = new OpenIdRelyingParty();            
    }
}

显然 OpenIdRelyingParty 需要访问 HttpContext,有没有办法模拟 OpenIdRelyingParty 并将其注入服务?或者也许可以模拟 HttpContext 并以某种方式将其提供给 OpenIdRelyingParty ?

4

3 回答 3

1

我会,因为您已经在这样做,所以OpenIdRelyingParty在您使用配置服务时注入您的构造函数。

除此之外,您可以在单元测试中模拟 HttpContext 。HttpContext.Current有一个 setter,所以将它设置为 mock/stub HttpContextBase。这是一个使用NSubstitute和 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
}

不过,这对我来说有点代码味道。它正在测试依赖项的依赖关系(或者无论兔子洞有多远)。但是,当重构不是一种选择时,它很有用。

于 2012-05-23T15:06:24.143 回答
1

要为 OpenIdRelyingParty 模拟 HttpContext,您应该修改该类的代码。即使你会浪费一些时间来嘲笑它,因为它是一个密封的类(但你可以使用MOCKWCF并非不可能)。

我认为最好为 OpenIdRelyingParty制作一个包装器或适配器。像:

public class OpenIdRelyingPartyWrapped
{
    private OpenIdRelyingParty openIdRelyingPartyTarget;
    ....
    public virtual IAuthenticationRequest CreateRequest(string text)
    {
        return this.openIdRelyingPartyTarget.CreateRequest(text);
    }
    ...
} 

然后,您将能够根据需要模拟它。

于 2012-05-23T15:35:29.020 回答
1

OpenIdRelyingParty可以通过使用接受 an 的方法重载在单元测试中使用HttpRequestBase,这是完全可模拟的。只有不将其作为参数的方法才需要HttpContext.Current.

于 2012-05-25T05:33:34.960 回答