使用Moq和接口进行单元测试

时间:2019-07-12 12:15:34

标签: c# interface moq

我不确定如何使用moq和接口在我的代码上正确运行单元测试。我正在创建一个简单的虚拟机,该虚拟机从文件中读取指令并创建要运行的这些指令的列表,我需要为每个指令创建单元测试。

我对使用c#接口和moq进行单元测试还很陌生,所以我不能完全确定我的哪个代码是正确的

例如,一条指令是将一个整数加载到虚拟机堆栈上。这是通过在VirtualMachine类中运行解析指令方法来完成的,该方法将虚拟机,操作码和操作数传递给JITCompiler,JITCompiler创建指令并将其返回以添加到指令列表中。然后调用该指令上的Run方法时,单元测试应确保已将正确的项添加到堆栈中(即int已正确加载)

解析指令(VirtualMachine类中的方法)

program.Add(JITCompiler.CompileInstruction(this, opcode, operands);

创建指令-使用反射在GAC中查找正确的类型

                Type[] typeArray = a.GetTypes();
            foreach (Type type in typeArray)
            {
                if (opcode.Equals(type.Name, StringComparison.InvariantCultureIgnoreCase))
                {
                    Object dynamicObj = Activator.CreateInstance(type);
                    instruction = (IInstructionWithOperand)dynamicObj;
                    instruction.Operands = operands;
                }
            }          
        instruction.VirtualMachine = vm;
        return instruction;
在SvmVirtualMachine类中,

会遍历指令列表并在每条指令上调用Run方法。 loadInt的Run方法如下所示

 public override void Run()
    {
        int opValue;
        if (!Int32.TryParse(this.Operands[0].ToString(), out opValue))
        {
            throw new SvmRuntimeException(String.Format(BaseInstruction.OperandOfWrongTypeMessage, 
                                            this.ToString(), VirtualMachine.ProgramCounter));
        }

        VirtualMachine.Stack.Push(opValue);
    }

我的虚拟机的界面是

  namespace SVM.VirtualMachine
{
    public interface IVirtualMachine
    {
        Stack Stack { get; set; }
        int ProgramCounter { get; set; }
        void Main(string[] args);
        void Compile(string filePath);
        void Run();
        void ParseInstruction(string instruction, int lineNumber);
        bool CommandLineIsValid(string[] args);
        void DisplayUserMessage(string message);
    }
}

到目前为止,这是我要进行单元测试的内容,但是我对从这里去哪里感到困惑

public void AddTest()
    {
        Mock<IVirtualMachine> vm = new Mock<IVirtualMachine>();
        int op1 = 5;
        int op2 = 3;
        vm.Setup(v => v.Stack.Push(op1));
        vm.Setup(v => v.Stack.Push(op2));
        vm.Setup(v => v.ParseInstruction("loadstring \"Calculating (2 + 3) - 1\"", 0));
        //IInstruction instruction = new IInstruction

    }

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

好的,我们开始。 要测试您的Run()成功完成并在Stack.Push()上调用IVirtualMachine,您的AddTest()可以进行如下更改:

[Test]
public void AddTest()
{
    var testStack = new Stack();
    // test case environment setup
    var vmMock = new Mock<IVirtualMachine>();
    vmMock.Setup(x => x.Stack).Returns(testStack);
    // instantiate LoadInt and intialize the instance
    var loadInt = new LoadInt()
    {
        Operands = new object[] {"123"},
        VirtualMachine = vmMock.Object,
    };
    // run test scenario
    loadInt.Run();
    // now we validate that stack has 123 added we could use something like nunit for that
    Assert.AreEqual(1, testStack.Count);
    Assert.AreEqual(123, testStack.Pop());
}

请注意,添加了对NUnit的引用以使用Assert并用AddTest()属性标记[Test]以便能够使用nunit运行器运行测试用例