簡體   English   中英

單個方法或通用 It.IsAny 的模擬行為松散

[英]Mock behavior loose for single method or generic It.IsAny

我有一個抽象類Shape和幾個繼承自它的類( SquareRectangleTriangleCircle ,...)。 我還有一個AreaCalculator類,其中包含一個名為CalculateAreasByShape()的方法。 此方法為每個Shape類型調用一系列CalculateShapeAreas<TShape>(List<TShape> shapes)方法。

現在,在我的單元測試中,我有以下代碼:

...
var areaMock = new Mock<AreaCalculator>(MockBehavior.Strict);
areaMock.Setup(m => m.CalculateAreasByShape()).Returns(new Dictionary<Type, decimal>());
var canvas = new DemoCanvas(shapes, perimeterMock.Object, areaMock.object);
var result = canvas.RunShapeCalculations();
...

這段代碼失敗了,因為MockBehavior設置為Strict並且沒有設置CalculateShapeAreas<TShape>()方法。 現在,我知道我可以為每個 Shape 類型運行一個設置,例如:

areaMock.Setup(m => m.CalculateShapeAreas<Triangle>(It.IsAny<List<Triangle>>())).Returns(default(decimal));

但這會產生很多重復的代碼。 我想知道我們是否可以使用所有形狀都繼承自同一個基類的事實。 我嘗試了以下方法,但不起作用:

areaMock.Setup(m => m.CalculateShapeAreas<Shape>(It.IsAny<List<Shape>>())).Returns(default(decimal));

或者,是否可以在單個泛型方法上設置MockBehavior.Loose (也就是說,它不會檢查實際類型)?

It.IsAny開放的通用支持尚不存在於moq (版本4.12.0)。 最終有一些計划介紹這個,看看這里


我認為您面臨的問題是因為您使用List<T>作為輸入參數。 您可能會注意到List<T>不是協變的。

那是什么意思?

List<Shape> shapeList;
IEnumerable<Shape> shapeEnumerable;
var triag = new List<Triangle>();

shapeList = triag; // NOT ALLOWED
shapeEnumerable = triag; // ALLOWED

嘲笑時同樣會產生問題。 一種解決方案可能是更改interface ,而不是傳遞List<T>傳遞IEnumerable<out T> ,或者正如@JeppeStigNielsen 指出的那樣IReadOnlyList<out T> 實際上,可以使用由List<T>實現的T接口中的任何協變。

areaMock
    .Setup(m => m.CalculateShapeAreas<Shape>(It.IsAny<IEnumerable<Shape>>()))
    .Returns(default(decimal));

暫無
暫無

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

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