我正在尝试为C#项目创建一个单元测试,其中我有一个我无法修改的外部类。它不是从Interface实现的,方法也不是虚拟的。
我想模拟从此类的方法返回的结果以及该方法将设置的任何类属性。
所以我在外部课
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#将始终调用声明它的变量的方法,即使它已被初始化为继承的。
关于如何进行此测试并模拟外部类的Process方法的任何想法?
由于
添
答案 0 :(得分:4)
您可以采取的一种方法是围绕RatioThreadProcessor
创建一个包装类:
class RatioThreadProcessorWrapper : IThreadProcessor
{
private readonly RatioThreadProcessor _ratioThreadProcessor;
public RatioThreadProcessorWrapper ()
{
_ratioThreadProcessor = new RatioThreadProcessor();
}
public Process() => ratioThreadProcessor.Process();
...
}
将其(通过参考IThreadProcessor
)注入FundInfoRatioService
。
但是,值得查看MethodUnderTest
方法。这个方法:
RatioThreadProcessor
,Process
,所以你有一种做四件事的方法。如果你移动方法的前三个并让它只有(4)的单一责任,那么你可以传入一个测试结果对象并以这种方式测试你的方法,将它与RatioThreadProcessor
分开。