How to do unit tests correctly
我正在尝试使用测试驱动设计方法编写应用程序 - 我对单元测试很新,所以我只是想知道测试正确输入和异常的正确方法是什么。
我有这个用于加载配置文件的类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class Config { private XmlDocument configfile; public Config() { configfile = new XmlDocument(); } public void LoadConfigFile(string filename) { if(string.IsNullOrEmpty(filename)) throw new System.ArgumentException("You must specify a filename"); try { configfile.Load(filename); } catch (Exception ex) { throw new System.IO.FileNotFoundException("File could not be loaded"); } } } |
因此,这里可以执行3个测试:
是测试这些的正确方法,编写3种测试方法,如下所示?:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /// <summary> ///A test for LoadConfigFile ///</summary> [TestMethod()] public void LoadConfigFileTest() { Config target = new Config(); // TODO: Initialize to an appropriate value string filename ="config.xml"; // TODO: Initialize to an appropriate value target.LoadConfigFile(filename); Assert.Inconclusive("A method that does not return a value cannot be verified."); } /// <summary> ///A test for LoadConfigFile ///</summary> [TestMethod()] [ExpectedException(typeof(System.ArgumentException))] public void LoadConfigFileTest1() { Config target = new Config(); // TODO: Initialize to an appropriate value string filename =""; // TODO: Initialize to an appropriate value target.LoadConfigFile(filename); Assert.Inconclusive("A method that does not return a value cannot be verified."); } /// <summary> ///A test for LoadConfigFile ///</summary> [TestMethod()] [ExpectedException(typeof(System.IO.FileNotFoundException))] public void LoadConfigFileTest2() { Config target = new Config(); // TODO: Initialize to an appropriate value string filename ="blah.xml"; // TODO: Initialize to an appropriate value target.LoadConfigFile(filename); Assert.Inconclusive("A method that does not return a value cannot be verified."); } |
此外,如果所有这三个测试都有try {} catch(){}语句吗?
与第一次测试一样,隐含了正确性,在第2次和第3次测试中,我正在检查异常,因此异常对测试没有影响。
你走的是正确的道路,但尚未到达。
很少有你需要调用
事实上,可以测试返回
应该没有try-catch块:它只会隐藏代码可能存在的任何问题。至于你的原始代码:不要捕获实际的异常并将其重新抛出为
扩展评论:
I wouldn't want a develper to mess around with the configfile property directly, so should I make it public for the test, then change it back to private?
这是一个很好的关注,并且每个开发人员在进行测试时都会面对它。重要的是要认识到单位的内部运作不是你应该经常测试的。实现细节正是它们的实现细节。然而,有时替代品甚至更不需要,所以你必须进行比较,无论你是否想要这样做。
这可能是一个合法的用例,幸运的是有一个相当不错的解决方法!我在这里详细介绍,但我建议使用内部构造函数,方法,属性或字段来
with regards to using stubs to test what's in configfile, it looks like I have to change everything to be interface dependant? Doesn't this just add tons more complexity that isn't needed?
定义"需要什么"。确实,通过定义接口并注入这些接口并在代码中有一个额外的抽象层,但这样做是有原因的:由于类的松散耦合性,您现在可以通过注入另一个实现来更轻松地测试它。
这个过程 - 依赖注入 - 是单元测试的支柱,也将有助于您的第一句话。