c# – 使用Moq是没有意义的,因为Returns()重新定义了方法的行为
我想让自己熟悉TDD.我试图找出如何使用Moq和NUnit.我创建了一个ICalculator接口,它有一个Add(decimal num1,decimal num2)方法和一个实现它的Calculator类.
我的问题是,通过指定特定值所在时应返回的内容,我基本上没有重新定义我的方法的工作方式吗?我的意思是,如果我突然让Add方法将数字相乘,我的测试仍然不会因为我改变它的工作方式而破坏. 我是否遗漏了一些关于Moq目的以及如何使用它的明显内容? var mockCalculator = new Mock<ICalculator>(); mockCalculator.Setup(mock => mock.Add(10m,25m)).Returns(35m); var calculator = mockCalculator.Object; var result = calculator.Add(10m,25m); Assert.That(result,Is.EqualTo(35m)); 我也尝试过遵循文章here,但它最终做了同样的事情 – 预定义结果,即使被测试的方法没有改变也不会改变. 解决方法
模拟的关键不是嘲笑你正在测试的中心代码,而是嘲笑它的依赖关系.当依赖关系是接口时,这最有效.假设你有这个界面:
public interface IFileLoader { string loadFileContents(string fileName); } 以及通过实际打开和读取该文件来实现它的类.然后,您有另一个使用该类的类: public class FileAnalyzer { private readonly IFileLoader _fileLoader; public FileAnalyzer(IFileLoader fileLoader) { _fileLoader = fileLoader; } public string Analyze(string fileName) { String contents = _fileLoader.loadFileContents(fileName); // (Some fancy algorithm here,resulting in some return value) } } 现在,您想要测试FileAnalyzer.Analyze(),它可能包含一些高级逻辑.实际上必须在磁盘上创建一个文件并在测试期间将其传递给该方法将是麻烦的;简单地将输入字符串保存在变量中会更容易.使用模拟框架,您可以模拟依赖FileLoader,从而能够专注于测试实际逻辑. [Test] public void TestAnalyze() { var mockLoader = new Mock<IFileLoader>(); mockLoader.Setup(ml => ml.loadFileContents("foo.txt")).Returns("Whatever you would have had in the file"); var analyzer = new FileAnalyzer(mockLoader.Object); Assert.That(analyzer.Analyze("foo.txt"),Is.EqualTo("Expected analysis result")); } 该测试根本不接触文件系统,因此更简单,更快速.在生产(非测试)代码中,您将使用实际从磁盘读取文件的IFileLoader的实际实现:new FileAnalyzer(new RealFileLoader()).另外,请注意FileAnalyzer不需要知道文件或者在生产中运行时数据来自文件以及在测试中运行时来自字符串的事实. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |