[英]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 = true
或false
正確了。
任何想法上面的代碼有什么問題嗎?
正如@ 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.