如何模拟未声明为虚拟的外部 class 中的方法
How can I Mock a method in an external class that is not declared as virtual
我正在尝试为 C# 项目创建单元测试,我有一个无法修改的外部 class。它不从接口实现,方法不是虚拟的。
我想模拟从这个 class 的方法返回的结果以及该方法将设置的任何 class 属性。
所以我在外部class
public class RatioThreadProcessor {
public SqlString dbName;
public List<Instrument> units;
public Results Results;
etc
public void Process() {
// Does stuff
// I want this to be called for real but not in my test case
}
我测试的代码是这样的:
public class FundInfoRatioService
{
public RatioThreadProcessor ratioThreadProcessor;
public FundInfoRatioService()
{
ratioThreadProcessor = new RatioThreadProcessor();
}
public MethodUnderTest()
{
ratioThreadProcesor.dbName = "as";
ratioThreadProcessor.Process();
var results = ratioThreadProcessor.Results;
// important logic I want to test
}
为了测试它,我想做类似的事情:
public class MockRatioThreadProcessor : RatioThreadProcessor
{
public new void Process()
{
// mock Logic
// I want this to be called in my test case
}
}
private Mock<RatioThreadProcessor> mockRatioThreadProcessor;
public void SetUp()
{
mockRatioThreadProcessor = new Mock<MockRatioThreadProcessor();
mockRatioThreadProcessor.SetUp(r => r.Process());
}
public void TestMethod()
{
var fundInfoRatioService = new FundInfoRatioService(null);
fundInfoRatioService.ratioThreadProcessor = mockRatioThreadProcessor.Object;
fundInfoRatioService.MethodUnderTest();
// assert results
}
我遇到的问题是始终调用基本 Process 方法,而不是我想调用的模拟方法。
我认为这是因为 C# 将始终调用它声明的变量的方法,即使它已被初始化为继承的方法。
关于如何进行此测试并模拟外部 class 的 Process 方法的任何想法?
谢谢
时间
您可以采取的一种方法是围绕 RatioThreadProcessor
:
创建包装器 class
class RatioThreadProcessorWrapper : IThreadProcessor
{
private readonly RatioThreadProcessor _ratioThreadProcessor;
public RatioThreadProcessorWrapper ()
{
_ratioThreadProcessor = new RatioThreadProcessor();
}
public Process() => ratioThreadProcessor.Process();
...
}
并将其(通过对 IThreadProcessor
的引用)注入 FundInfoRatioService
.
但是,MethodUnderTest
方法值得一看。此方法:
- 修改
RatioThreadProcessor
、 的实例
- 调用
Process
、
- 得到一些结果,
- 对结果做些什么。
所以你有一个方法可以做四件事。如果您将前三个移出该方法并让它承担 (4) 的单一职责,那么您可以传入一个测试结果对象并以这种方式测试您的方法,将其与 RatioThreadProcessor
.[= 解耦18=]
我正在尝试为 C# 项目创建单元测试,我有一个无法修改的外部 class。它不从接口实现,方法不是虚拟的。
我想模拟从这个 class 的方法返回的结果以及该方法将设置的任何 class 属性。
所以我在外部class
public class RatioThreadProcessor {
public SqlString dbName;
public List<Instrument> units;
public Results Results;
etc
public void Process() {
// Does stuff
// I want this to be called for real but not in my test case
}
我测试的代码是这样的:
public class FundInfoRatioService
{
public RatioThreadProcessor ratioThreadProcessor;
public FundInfoRatioService()
{
ratioThreadProcessor = new RatioThreadProcessor();
}
public MethodUnderTest()
{
ratioThreadProcesor.dbName = "as";
ratioThreadProcessor.Process();
var results = ratioThreadProcessor.Results;
// important logic I want to test
}
为了测试它,我想做类似的事情:
public class MockRatioThreadProcessor : RatioThreadProcessor
{
public new void Process()
{
// mock Logic
// I want this to be called in my test case
}
}
private Mock<RatioThreadProcessor> mockRatioThreadProcessor;
public void SetUp()
{
mockRatioThreadProcessor = new Mock<MockRatioThreadProcessor();
mockRatioThreadProcessor.SetUp(r => r.Process());
}
public void TestMethod()
{
var fundInfoRatioService = new FundInfoRatioService(null);
fundInfoRatioService.ratioThreadProcessor = mockRatioThreadProcessor.Object;
fundInfoRatioService.MethodUnderTest();
// assert results
}
我遇到的问题是始终调用基本 Process 方法,而不是我想调用的模拟方法。
我认为这是因为 C# 将始终调用它声明的变量的方法,即使它已被初始化为继承的方法。
关于如何进行此测试并模拟外部 class 的 Process 方法的任何想法?
谢谢
时间
您可以采取的一种方法是围绕 RatioThreadProcessor
:
class RatioThreadProcessorWrapper : IThreadProcessor
{
private readonly RatioThreadProcessor _ratioThreadProcessor;
public RatioThreadProcessorWrapper ()
{
_ratioThreadProcessor = new RatioThreadProcessor();
}
public Process() => ratioThreadProcessor.Process();
...
}
并将其(通过对 IThreadProcessor
的引用)注入 FundInfoRatioService
.
但是,MethodUnderTest
方法值得一看。此方法:
- 修改
RatioThreadProcessor
、 的实例
- 调用
Process
、 - 得到一些结果,
- 对结果做些什么。
所以你有一个方法可以做四件事。如果您将前三个移出该方法并让它承担 (4) 的单一职责,那么您可以传入一个测试结果对象并以这种方式测试您的方法,将其与 RatioThreadProcessor
.[= 解耦18=]