0

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

[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:在 System.Web.HttpClientCertificate..ctor(HttpContext context) 在 System.Web.HttpRequest.CreateHttpClientCertificateWithAssert() 在 System.Web.HttpRequest.get_ClientCertificate() 在 (我的方法) 在 TestMyService()

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

4

1 回答 1

0

我自己找到了解决方案。因为异常来自 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,我从文件中创建了该对象(也可以从证书存储中完成)。

于 2013-08-22T07:58:27.817 回答