【发布时间】:2021-10-10 10:04:44
【问题描述】:
我一直在阅读,似乎找不到与我想要的 Moq 行为相匹配的案例。
我想模拟要测试的类的特定方法(与外部 API 接口)。问题是,据我了解,一旦类为.Create<T>,您就不能在其上使用.Setup()... 任何方法。
这是一个例子:
public class ClassA
{
public void ConfigureExpansion()
{
var classB = new ClassB();
var data = GetExternalData(); // I want to mock this
//data is used in the code
classB.TaskB(data); // I want to mock this
}
public string GetExternalData()
{
return data...
}
}
public class ClassB
{
public void TaskB(String myData)
{
//Does some work
}
}
[TestMethod]
public void Test()
{
using (var mock = AutoMock.GetLoose())
{
mock.Mock<IClassB>().Setup(x => x.TaskB(It.IsAny<string>()));
var cls = mock.Create<ClassA>();
cls.Setup(x => x.GetExternalData(It.IsAny<string>())).Return("MyData"); // <--- This is not valid, but represents what I am trying to do.
//act
cls.ConfigureExpansion();
mock.Mock<IClassB>().Verify(x => x.TaskB(), Times.Once);
}
}
我试图为我的测试类的接口设置一个模拟,但cls 不会调用它:
[TestMethod]
public void Test()
{
using (var mock = AutoMock.GetLoose())
{
mock.Mock<IClassA>().Setup(x => x.GetExternalData(It.IsAny<string>())).Return("MyData"); //<--- Mocking the method here is not detected by the cls below
mock.Mock<IClassB>().Setup(x => x.TaskB(It.IsAny<string>()));
var cls = mock.Create<ClassA>();
//act
cls.ConfigureExpansion();
mock.Mock<IClassB>().Verify(x => x.TaskB(), Times.Once);
}
}
我也尝试过实例化我的被测类,当我这样做时,它不会考虑模拟(ClassB):
[TestMethod]
public void Test()
{
using (var mock = AutoMock.GetLoose())
{
mock.Mock<IClassA>().Setup(x => x.GetExternalData(It.IsAny<string>())).Return("MyData"); //<--- Mocking the method here is not detected by the cls below
mock.Mock<IClassB>().Setup(x => x.TaskB(It.IsAny<string>()));
var cls = new ClassA();
//act
cls.ConfigureExpansion();
mock.Mock<IClassB>().Verify(x => x.TaskB(), Times.Once);
}
}
我非常感谢您对此的任何见解, 谢谢
【问题讨论】:
-
如果
cls(或ClassA)是你的被测类,那么你应该使用它的构造函数来创建,而不是它的模拟版本。IClassB和ClassA之间有什么关系?它是ClassA的依赖项吗? -
我可能会误解 .Create 的目的。我认为这就是你应该如何实例化你的测试类。关于 IClassB 和 ClassA,关系类似于数据库接口类,它包含所有查询,我想在这种情况下模拟这些查询。 ClassA 利用 ClassB 获取数据。
-
@Phyziik 你能否用要测试的代码来扩展你的问题?我什至不确定您的测试的哪一行应该被视为 Act 阶段。你想评估什么?
-
@PeterCsala 你完全正确,我的问题是缺少代码上下文。我彻底检查了问题的代码部分。希望它更清楚。对不起。
-
@Phyziik 感谢您分享这段代码。问题是你不能像这样嘲笑
classB。ClassA应该在其构造函数中接收一个IClassB实例以便能够模拟它。此外,如果您想模拟GetExternalData,那么您应该使用模拟的CallBase功能来完成。如果您希望我可以留下一个帖子来更详细地解释这两个概念
标签: c# unit-testing mocking moq autofac