我如何伪造System.Web.HttpClientCertificate?

时间:2013-08-20 14:00:34

标签: c# mocking client certificate

我想为WCF Web服务编写单元测试。该服务使用HttpContext.Current。我已经设法通过向System.Web添加假组件和一些代码来伪造它:

[Test]
public void TestMyService()
{
  using (ShimsContext.Create())
  {
    HttpRequest httpRequest = new HttpRequest("", "http://tempuri.org", "");
    HttpContext httpContext = new HttpContext(httpRequest, new HttpResponse(new StringWriter()));
    System.Web.Fakes.ShimHttpContext.CurrentGet = () => { return httpContext; };
    System.Web.Fakes.ShimHttpClientCertificate.AllInstances.IsPresentGet = (o) => { return true; };
  }
}

但我的服务还需要ClientCertificate:

if (!HttpContext.Current.Request.ClientCertificate.IsPresent) // <== Exception in unit test!
  throw new Exception("ClientCertificate is missing");
_clientCertificate = new X509Certificate2(HttpContext.Current.Request.ClientCertificate.Certificate);

现在在标记的行中,单元测试抛出NullReferenceException:

  

结果消息:System.NullReferenceException:不是对象引用   设置为对象的实例。结果StackTrace:at   System.Web.HttpClientCertificate..ctor(HttpContext context)at   System.Web.HttpRequest.CreateHttpClientCertificateWithAssert()at   System.Web.HttpRequest.get_ClientCertificate()at(my method)at   TestMyService()

如何为单元测试设置ClientCertificate?我不知道如何通过Shim创建一个HttpClientCertificate对象,因为没有合适的构造函数。

1 个答案:

答案 0 :(得分:0)

我自己找到了解决方案。 因为Exception来自HttpClientCertificate的构造函数,所以我也不得不伪造它。我在伪造的构造函数中什么都不做:

System.Web.Fakes.ShimHttpClientCertificate.ConstructorHttpContext = (o, httpCont) => { };

此外,为了在我的单元测试中使用 HttpContext.Current.Request.ClientCertificate.Certificate 获取有用的客户端证书,我假冒:

byte[] clientCertBytes = {0x30, 0x82, 0x03, ...., 0xd3};
System.Web.Fakes.ShimHttpClientCertificate.AllInstances.CertificateGet = (o) =>
  {
    return clientCertBytes;
  };

clientCertBytes是我在调试会话中创建的X509Certificate2对象的RawData,我在该调试会话中从文件创建此对象(也可以从证书存储中完成)。