簡體   English   中英

如何驗證一個方法是否在另一個方法內部被調用

[英]How can I verify if a method is called inside another method

我試圖找到一個例子,但是沒有成功,所以這就是為什么我問這個問題。

讓我們從一些代碼開始。 這是我的代碼:

class Dummy
{
    public void DoDummyThings1()
    {
        Console.WriteLine("Sorry, I'm dummy 1...");
    }

    public void DoDummyThings2()
    {
        Console.WriteLine("Sorry, I'm dummy 2...");
    }

    public void DoDummyThings3()
    {
        Console.WriteLine("Sorry, I'm dummy 3...");
    }
}

和我的測試代碼:

[TestClass]
public class UnitTest
{
    private Dummy dum = new Dummy();

    [TestInitialize()]
    public void SetUp()
    {
        MethodInfo mi = typeof (UnitTest).GetMethod("TestDummy");
        MethodBody mb = mi.GetMethodBody();
    }

    [TestMethod]
    public void TestDummy()
    {
        this.dum.DoDummyThings1();
        this.dum.DoDummyThings2();
        this.dum.DoDummyThings3();
    }
}

這就是我想要做的。 我想在執行每個測試方法之前,先查看測試方法,然后檢查是否將調用Dummy類的方法DoDummyThings1,DoDummyThings2和DoDummyThings3。

目的是,根據調用哪種DoDummyThingsX方法,我想在代碼內部深處注入不同的實現,以在運行時修改某些類的行為(將接口的注入實現換成另一個)。

有人可以向我解釋如何正確執行此操作(使用最新版本的Cecil或C#的其他版本)嗎? 有沒有不使用.dll文件的方法? (當前,這是我弄清楚如何執行此操作的唯一方法,但是,對於我來說,無法將字符串作為“ MyDllName.dll”和“ MyNamespace.MyClassName”硬編碼使用)

我已經知道的其他stackoverflow線程:

有人可以幫我提供一個完整(但簡單)的示例(如果可能)嗎? 謝謝!

此答案演示了如何確定哪些測試執行了Dummy方法,但沒有答案:

在代碼深處注入不同的實現,以在運行時修改某些類的行為

反射不能提供對所需單元測試方法的IL主體的詳細訪問; 但是Cecil提供了此功能。 以下linq返回內部調用DoDummyThings1的方法的列表。 linq可能會更有效,但是我想使其盡可能清晰。 where子句是重要的部分。

//syntax based on version 0.9.5.4 (http://nuget.org/packages/Mono.Cecil/0.9.5.4)
using Mono.Cecil;  
using Mono.Cecil.Cil;
//...
string assemblyPath = (@"path to your unit test assembly\MyTests.dll");
AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(assemblyPath);

List<MethodDefinition> testsThatCallDummyMethods =
       (from mod in asm.Modules
        from t in mod.Types
        from meth in t.Methods
        where meth.HasBody
        from instr in meth.Body.Instructions
        let op = instr.Operand as MethodDefinition
        where
            instr.OpCode == OpCodes.Callvirt &&
            op != null &&
            op.DeclaringType.FullName ==
            "Lib.Dummy" //namespace qualified type name
            && op.Name ==
            "DoDummyThings1" //method names...
        select meth)
        .ToList();

使用ILDasm拆卸測試程序集以找出操作碼/操作數。 TestDummy方法的相關部分將類似於:

  //this.dum.DoDummyThings1();
  IL_0001:  ldarg.0
  IL_0002:  ldfld      class Lib.Dummy Lib.UnitTest::dum
  IL_0007:  callvirt   instance void Lib.Dummy::DoDummyThings1()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM