C#中的单元测试:第二次调用模拟方法时返回另一个var
本文关键字:方法 返回 另一个 var 模拟 调用 单元测试 第二次 | 更新日期: 2023-09-27 17:59:17
当尝试对方法进行单元测试时,我遇到了一个问题。该方法的任务是移动树中的节点。该树是通过"预订单树遍历"方法构建的。http://blogs.sitepoint.com/hierarchical-data-database-2/此方法使用节点的"左"answers"右"值将其定位在树中。
在方法中,将更改节点的Lft和Rgt值。在我的测试用例中,我将把节点"Meat"移到"Banana"下。
var Food = new Node { Id = Guid.NewGuid(), Title = "Food", Ordinal = 0,Depth = 0, Lft = 1, Rgt = 18};
var Fruit = new Node { Id = Guid.NewGuid(), Title = "Fruit", ParentNode = Food, Depth = 1, Ordinal = 0, Lft = 2, Rgt = 11 };
var Red = new Node { Id = Guid.NewGuid(), Title = "Red", ParentNode = Fruit, Depth = 2, Ordinal = 0, Lft = 3, Rgt = 6 };
var Cherry = new Node { Id = Guid.NewGuid(), Title = "Cherry", ParentNode = Red, Depth = 3, Ordinal = 0, Lft = 4, Rgt = 5 };
var Yellow = new Node { Id = Guid.NewGuid(), Title = "Yellow", ParentNode = Fruit, Depth = 2, Ordinal = 1, Lft = 7, Rgt = 10 };
var Banana = new Node { Id = Guid.NewGuid(), Title = "Banana", ParentNode = Yellow, Depth = 3, Ordinal = 0, Lft = 8, Rgt = 9 };
var Meat = new Node { Id = Guid.NewGuid(), Title = "Meat", ParentNode = Food, Depth = 1, Ordinal = 1, Lft = 12, Rgt = 17 };
var Beef = new Node { Id = Guid.NewGuid(), Title = "Beef", ParentNode = Meat, Depth = 2, Ordinal = 0, Lft = 13, Rgt = 14 };
var Pork = new Node { Id = Guid.NewGuid(), Title = "Pork", ParentNode = Meat, Depth = 2, Ordinal = 1, Lft = 15, Rgt = 16 };
var allNodes = new List<Node> {Food, Fruit, Red, Cherry, Yellow, Banana, Meat, Beef, Pork};
var descendantsOfNodeFood = new List<Node>
{
Beef,
Cherry,
Red,
Yellow,
Pork,
Banana,
Meat,
Fruit
};
var descendantsOfNodeFruit = new List<Node>
{
Red,
Cherry,
Banana,
Yellow
};
var descendantsOfNodeRed = new List<Node>
{
Cherry
};
var descendantsOfNodeCherry = new List<Node> { };
var descendantsOfNodeYellow = new List<Node>
{
Banana
};
var descendantsOfNodeBanana = new List<Node> { };
var descendantsOfNodeMeat = new List<Node>
{
Beef,
Pork
};
var descendantsOfNodeBeef = new List<Node> { };
var descendantsOfNodePork = new List<Node> { };
//Mock the node repository
_mockNodeRepository.Setup(x => x.LoadNode(Food.Id)).Returns(Food);
_mockNodeRepository.Setup(x => x.GetDescendants(Food.Id, It.IsAny<bool>())).Returns(descendantsOfNodeFood);
_mockNodeRepository.Setup(x => x.GetDescendants(Fruit.Id, It.IsAny<bool>())).Returns(descendantsOfNodeFruit);
_mockNodeRepository.Setup(x => x.GetDescendants(Red.Id, It.IsAny<bool>())).Returns(descendantsOfNodeRed);
_mockNodeRepository.Setup(x => x.GetDescendants(Cherry.Id, It.IsAny<bool>())).Returns(descendantsOfNodeCherry);
_mockNodeRepository.Setup(x => x.GetDescendants(Yellow.Id, It.IsAny<bool>())).Returns(descendantsOfNodeYellow);
_mockNodeRepository.Setup(x => x.GetDescendants(Banana.Id, It.IsAny<bool>())).Returns(descendantsOfNodeBanana);
_mockNodeRepository.Setup(x => x.GetDescendants(Meat.Id, It.IsAny<bool>())).Returns(descendantsOfNodeMeat);
_mockNodeRepository.Setup(x => x.GetDescendants(Beef.Id, It.IsAny<bool>())).Returns(descendantsOfNodeBeef);
_mockNodeRepository.Setup(x => x.GetDescendants(Pork.Id, It.IsAny<bool>())).Returns(descendantsOfNodePork);
_mockNodeRepository.Setup(x => x.GetNodes()).Returns(allNodes);
运行测试时,除Meat的Lft和Rgt值外,所有值都设置为正确值。(应该是9-10)我将问题追溯到方法"GetDescendants(Meat.Id,It.IsAny())"的mock。在我尝试测试的方法中,这个方法将被调用两次。第一次它应该返回一个节点为"牛肉"answers"猪肉"的列表。第二次,节点"牛肉"被放在"香蕉"下,它应该返回一个只有节点"猪肉"的列表。
谁能帮我弄清楚mock第一次如何返回一个有2个节点的列表,第二次如何返回只有一个节点的名单?
我使用"Microsoft.VisualStudio.TestTools.UnitTesting;"answers"Moq;"进行单元测试。
returning different values on each invocation
var mock = new Mock<IFoo>();
var calls = 0;
mock.Setup(foo => foo.GetCountThing())
.Returns(() => calls)
.Callback(() => calls++);
// returns 0 on first invocation, 1 on the next, and so on
Console.WriteLine(mock.Object.GetCountThing());
发件人:http://code.google.com/p/moq/wiki/QuickStart
然而,如果您的模拟设置如此复杂,那么最好使用内存中的数据库或您正在使用的任何数据库。模仿逻辑是非常脆弱和难以阅读的。
回答您的意见:
var mock = new Mock<IFoo>();
bool firstCall = true;
mock.Setup(foo => foo.GetCountThing())
.Returns(() => firstCall ? list1 : list2)
.Callback(() => firstCall = false);
应该为所有后续调用返回第一个列表,然后返回第二个列表。