如何模拟HttpClientCertificate? [英] How to mock HttpClientCertificate?

查看:74
本文介绍了如何模拟HttpClientCertificate?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对我编写的动作过滤器进行单元测试.我想模拟HttpClientCertificate,但是使用MOQ时会出现异常. HttpClientCertificate没有公共的默认构造函数.

I am trying to unit test an action filter I wrote. I want to mock the HttpClientCertificate but when I use MOQ I get exception. HttpClientCertificate doesnt have a public default constructor.

代码:

//Stub HttpClientCertificate </br>
var certMock = new Mock<HttpClientCertificate>();
HttpClientCertificate clientCertificate = certMock.Object;
requestMock.Setup(b => b.ClientCertificate).Returns(clientCertificate);
certMock.Setup(b => b.Certificate).Returns(new Byte[] { });

推荐答案

这是在.NET中创建单元可测试系统的最尴尬的情况.最后,我总是在无法模拟的组件上添加抽象层.通常,对于具有无法访问的构造函数(例如这种情况),非虚拟方法或扩展方法的类,这是必需的.

This is the most awkward case of creating unit testable systems in .NET. I invariable end up adding a layer of abstraction over the component that I can't mock. Normally this is required for classes with inaccessible constructors (like this case), non-virtual methods or extension methods.

这是我使用的模式(我认为是适配器模式),它类似于MVC团队对所有RequestBase/ResponseBase类所做的事情使其可以进行单元测试.

Here is the pattern I use (which I think is Adapter pattern) and is similar to what MVC team has done with all the RequestBase/ResponseBase classes to make them unit testable.

//Here is the original HttpClientCertificate class
//Not actual class, rather generated from metadata in Visual Studio

public class HttpClientCertificate : NameValueCollection {
    public byte[] BinaryIssuer { get; }
    public int CertEncoding { get; }
    //other methods
    //...
}

public class HttpClientCertificateBase {
    private HttpClientCertificate m_cert;

    public HttpClientCertificateBase(HttpClientCertificate cert) {
       m_cert = cert;
    }
    public virtual byte[] BinaryIssuer { get{return m_cert.BinaryIssuer;} }
    public virtual int CertEncoding { get{return m_cert.CertEncoding;} }
    //other methods
    //...
}

public class TestClass {
  [TestMethod]
  public void Test() {
      //we can pass null as constructor argument, since the mocked class will never use it and mock methods will be called instead
      var certMock = new Mock<HttpClientCertificate>(null);
      certMock.Setup(cert=>cert.BinaryIssuer).Returns(new byte[1]);
  }
}

在使用HttpClientCertificate的代码中,您改为使用HttpClientCertificateBase,您可以像这样实例化-new HttpClientCertificateBase(httpClientCertificateInstance).这样,您就可以创建一个测试图面,以插入模拟对象.

In your code that uses HttpClientCertificate you instead use HttpClientCertificateBase, which you can instantiate like this - new HttpClientCertificateBase(httpClientCertificateInstance). This way you are creating a test surface for you to plug in mock objects.

这篇关于如何模拟HttpClientCertificate?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆