使用MOQ为复杂操作创建Mock参考和设置方法

时间:2017-07-03 06:54:02

标签: c# .net unit-testing mocking moq

我有两个方法,OpenCertificateStore和FindCertificateBySubjectName,并按如下方式实现:

 public void OpenCertificateStore()
        {
            if (_certificateStore == default(X509Store))
                _certificateStore = new X509Store(StoreLocation.CurrentUser);

            _certificateStore.Open(OpenFlags.ReadOnly | OpenFlags.IncludeArchived);
        }

        public X509Certificate2Collection FindCertificateBySubjectName(string certificateSubjectName)
        {
            X509Certificate2Collection certificates = new X509Certificate2Collection();
            if (_certificateStore != default(X509Store))
            {
                certificates = _certificateStore.Certificates.Find(X509FindType.FindBySubjectName, certificateSubjectName, true);
            }

            return certificates;
        }

我的单元测试如下:

[TestClass]
    public class MyHealthTests
    {
        private Mock<Logger> _logger;
        private Mock<MYCertificateManager> _certManager;

        [TestInitialize]
        public void Initialize()
        {
             _logger = new Mock<Logger>();
             _certManager = new Mock<MYCertificateManager>();
        }

        [TestMethod]
        public void PassName_FindCertiFicatebyName_ShouldReturnValid()
        {


            MyCertificateHelper myCertHelper = new MyCertificateHelper(_logger.Object,_certManager.Object);

            myCertHelper.OpenCertificateStore();
            var certNameCollection = myCertHelper.FindCertificateBySubjectName("Valid Cert Name");
            Assert.IsNotNull(certNameCollection);
            Assert.IsTrue(certNameCollection.Count > 0);
        }
    }

哪种方法很好,但如果我能找到一种方法来模仿myCertHelper,情况会好很多。

如果我做了mok,它会返回null,因为它不会查询实际的证书存储。

1 个答案:

答案 0 :(得分:2)

你如何模仿MyCertificateHelper

你没有。

这样做没有任何好处。如果你这样做了,那么测试中的所有类都将被模拟掉,你将不再真正测试任何代码。此时,您也可以删除测试。它不会做任何事情,但会花费你的钱来维持它。

  • My前缀所有内容是没用的。比无用更糟糕,它是嘈杂和分散注意力的。算了吧。
  • 我不喜欢你设计中的时间耦合。我不喜欢需要调用OpenInit等方法。忘记打电话或打电话太多次很容易。如果构造函数将类置于可用状态,那就更好了。
  • 你注射和踢开记录器很好,但我发现注射记录器是一种代码味道。我发现让我的课程提升事件并让记录器监听这些事件会更好。它不需要一直模拟记录器,并为其他代码提供了很好的钩子。这种事件驱动的设计最终会出现在扩展方面更加开放的代码,但是对于修改是封闭的。