简体   繁体   English

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

[英]Creating Mock reference and setup methods for complex operations using MOQ

I have two methods , OpenCertificateStore and FindCertificateBySubjectName and implemented them as following: 我有两个方法,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;
        }

I have my unit test as below: 我的单元测试如下:

[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);
        }
    }

Which works fine , but it would be lot better if I can find a way to mock myCertHelper . 哪个工作正常,但如果我能找到一种模拟myCertHelper的方法会myCertHelper

If I do mok them , it returns null as it's not querying actual certificate store. 如果我做了mok,它返回null,因为它不查询实际的证书存储。

How do you mock MyCertificateHelper ? 你如何模仿MyCertificateHelper

You don't. 你没有。

Doing so would have no benefit. 这样做没有任何好处。 If you did, then all of the classes in your test would be mocked out and you would no longer actually be testing any of your code. 如果你这样做了,那么测试中的所有类都将被模拟掉,你将不再真正测试任何代码。 At that point, you might as well delete the test. 此时,您也可以删除测试。 It wouldn't do anything but cost you money to maintain it. 它不会做任何事情,但会花费你的钱来维持它。


  • Prefixing everything with My is useless. My前缀一切是没用的。 Worse than useless, it's noisy and distracting. 比无用更糟糕,它是嘈杂和分散注意力的。 Drop it. 算了吧。
  • I don't like the temporal coupling in your design. 我不喜欢你设计中的时间耦合。 I don't like needing to call methods like Open or Init . 我不喜欢需要调用OpenInit等方法。 It's easy to forget to call it or call it too many times. 忘记打电话或打电话太多次很容易。 It's better if the constructor puts the class into a usable state. 如果构造函数将类置于可用状态,那就更好了。
  • It's nice that you're injecting and kicking the logger, but I find injecting loggers to be a code smell. 你注射和踢动记录器很好,但我发现注射记录器是一种代码味道。 I find it's much nicer to have my classes raise events and have the logger listen for those events. 我发现让我的课程提升事件并让记录器监听这些事件会更好。 It removes the need to mock the logger all the time and provides nice hooks for other code to leverage. 它不需要一直模拟记录器,并为其他代码提供了很好的钩子。 This kind of event driven design ends up in code that is much more open to extension, but closed for modification. 这种事件驱动的设计最终会出现在扩展方面更加开放的代码,但是对于修改是封闭的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM