如何模拟HttpClientCertificate? [英] How to mock 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屋!