与Moq斗争-在被测方法中使用Moq

问题描述

在我的系统中,我有一个单例类,该类负责列出和取消列出所选的USB设备。此类是“ InterfaceHandler”。
现在,我正在尝试测试此类,大概需要使用Mocking(在这种情况下为Moq)。
除其他外,InterfaceHandler必须实例化检测到的任何硬件接口。这是在称为“ CreateCommunicationInterface()”的方法中完成的,如下所示:

public class InterfaceHandler {
   public IHardware Hardware { get; set; }

   private InterfaceHandler() {}

   private static InterfaceHandler _instance;
   public static InterfaceHandler Instance() => (_instance) ?? (_instance = new InterfaceHandler());

   public IHardware CreateCommunicationInterface(HardwareType detectedHardwareType) {
       try {
           lock (locker) {
               // Create and initialise hardware interface
               switch (detectedHardwareType) {
                case "Harware0":
                    Hardware = new HW0();
                    break;
                case "Harware1":
                    Hardware = new HW1();
                    break;
                case "SimHarware":
                    Hardware = new Simulator();
                    break;
                default:
                    throw new Exception("UnkNown Hardware Interface");
               }
            
               // Do something with this Hardware
            }
        } catch (Exception ex) {
            string errorMessage = LogUtils.ComposeErrorMessage(ex,$"Could not create communication interface.");
            Logger.Error(errorMessage);
        }

        return Hardware;
    }
}

我这里遇到的问题是,如果我要创建一个单元测试并为每个接口(HW0,HW1和Simulator)创建一个Moq,那么CreateCommunicationInterface()将无法使用这些Moq。 ed对象(用于测试CreateCommunicationInterface())。
我看到在很多情况下,人们会在构造时注入一个Interface,但是在这种情况下,我们不知道在构造时需要实例化什么,因此我不确定该遵循哪种方法
任何指导将不胜感激。

解决方法

您应该在这里问的问题是要测试什么。

让我们定义单位:您的单位就是适当对象的构造。

对象本身将在为此专门设计的另一个单元测试类中进行测试。所以你会

  1. HW0测试班
  2. HW1测试班

因此,在您的单元测试中,根据输入,您检查返回的实例是否具有正确的类型,并已完成操作。

现在,如果要测试使用者,则需要模拟InterfaceHandler

为此,您需要使用IInterfaceHandler函数作为成员声明一个新接口CreateCommunicationInterface,并让InterfaceHandler实现它。然后,您可以控制流程,而不管您的单例实现如何。

另一点。您真的需要以下行吗?

   public IHardware Hardware { get; set; }

由于它是单例,因此如果多个线程使用它并且可能用于不同的硬件,则可能会遇到奇怪的结果,总是将最新接口分配给成员变量。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...