簡體   English   中英

即使在CallBase = true / false之后,原始方法仍會在Moq中被調用

[英]Original method still getting called in Moq even after CallBase = true/false

這是我的代碼:

public class Bar { }

public class Foo { public string Name { get; set; } public Bar TheBar { get; set; } }

public class Dependency
{
    public Foo DoSomething(Expression<Func<Foo, bool>> exp1) { return new Foo(); }
}

public class Base
{
    public Dependency Dependency { get; set; }
    public virtual Foo MethodA(Expression<Func<Foo, bool>> exp1,
                               params Expression<Func<Foo, object>>[] exp2)
    {
        return Dependency.DoSomething(exp1);
    }
}

public class Derived : Base
{
    public Foo DerviedMethod(string str)
    {
        return base.MethodA(e1 => e1.Name.Equals(str), e2 => e2.TheBar);
    }
}

和我的單元測試代碼:

var mock = new Mock<Derived> { CallBase = true }; // Same result with false
mock
   .Setup(m => m.MethodA(
      It.IsAny<Expression<Func<Foo, bool>>>(),
      It.IsAny<Expression<Func<Foo, object>>>()
      ))
   .Returns(new Foo());

// Act
var result = mock.Object.DerviedMethod("test");

// Assert
Assert.IsNotNull(result);

但是它仍然調用原始方法,而不是模擬方法。 這兩個類都存在於同一程序集中。

我已經搜索過它,幾乎所有人都使用CallBase = truefalse正確了。

任何想法上面的代碼有什么問題嗎?

正如@ Pierre-Luc在評論中所建議的那樣,提取基類並將其作為依賴項注入可能是更好的方法(我一直認為嘲笑您實際上試圖測試的類感覺不對)。

也就是說,為了能夠模擬類的調用,需要通過VTable進行。 本質上,模擬框架創建了虛擬方法的新實現。 正常調用時,此版本的方法會運行,然后可以攔截調用。 有問題的行是這一行:

return base.MethodA(e1 => e1.Name.Equals(str), e2 => e2.TheBar);

因為您是通過base關鍵字顯式調用MethodA ,所以它告訴編譯器調用該方法的特定版本。 總是被稱為基本實現。 這意味着模擬無法攔截呼叫。

將方法更改為:

public Foo DerviedMethod(string str) {
    return MethodA(e1 => e1.Name.Equals(str), e2 => e2.TheBar);
}

允許MethodA方法。 從設計的角度來看這是否正確取決於您。

暫無
暫無

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

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