我之前没有使用过Junit,也没有自动进行单元测试。
情境: 我们正在将后端DAO从Sql Server更改为Oracle。所以在DB端,所有存储过程都转换为oracle。现在,当我们的代码调用这些Oracle存储过程时,我们希望确保返回的数据与sql server存储过程相比是相同的。
例如,我在DAO中有以下方法:
//this is old method. gets data from sql server
public IdentifierBean getHeadIdentifiers_old(String head){
HashMap parmMap = new HashMap();
parmMap.put("head", head);
List result = getSqlMapClientTemplate().queryForList("Income.getIdentifiers", parmMap);
return (IdentifierBean)result.get(0);
}
//this is new method. gets data from Oracle
public IdentifierBean getHeadIdentifiers(String head){
HashMap parmMap = new HashMap();
parmMap.put("head", head);
getSqlMapClientTemplate().queryForObject("Income.getIdentifiers", parmMap);
return (IdentifierBean)((List)parmMap.get("Result0")).get(0);
}
现在我想编写一个Junit测试方法,首先调用getHeadIdentifiers_old
然后调用getHeadIdentifiers
并比较返回的对象(必须覆盖等于IdentifierBean
中的哈希值)。只有当两个对象相同时,测试才会通过。
在测试器方法中,我将为这两种方法提供一个参数(在这种情况下是头部)。这将暂时手动完成。是的,从前端参数可能不同,SP可能无法返回这些参数的确切结果。但我认为有这些测试用例会让我们感到宽慰,他们会返回相同的数据......
我的问题是:
答案 0 :(得分:3)
好的,让我们看看可以做些什么......
这是一个好方法吗?
不是真的。由于您现在拥有两个具有不相等且不可预测的功能的代码路径,而不是拥有一个具有某种已知功能的过时代码路径。通常会先为遗留代码创建彻底的单元测试,然后重构原始方法以避免令人难以置信的大量重构 - 如果构成巨大应用程序的代码丛的某些部分继续调用其他方法,而其他部分调用新的?
然而,使用遗留代码绝不是最佳选择,因此您的想法可能是最佳解决方案。
我将有多个DAO。我是否在DAO本身或每个DAO中编写测试方法我应该有一个单独的JUnit测试类?
假设你已经用你的程序结构正确地完成了OO,其中每个类只做一件事,只有一件事,是的,你应该创建另一个包含该个别类的测试用例的类。你在这里寻找的是模拟对象(一般在SO和Google上搜索它,提供大量信息),它可以帮助你将你的课程与其他课程分开。有趣的是,单元测试中大量的模拟通常意味着你的课程可能会使用一些重型重构。
(可能是n00b问题)所有测试用例都会自动运行吗?我不想去前端点击一堆东西,以便触发对DAO的调用。
所有IDE:允许您同时运行所有JUnit测试,例如在Eclipse中只需单击源文件夹/顶部包并选择Run - > Junit测试。此外,在运行单个类时,其中包含的所有单元测试都在适当的JUnit流程中运行(setup()
- > testX()
- > tearDown()
)。
运行测试时,我会找出哪些方法失败了?对于那些失败的人,它会告诉我失败的测试方法吗?
是的,测试驱动开发的一部分是咒语Red-Green-Refactor,它指的是IDE显示的彩色条:s用于单元测试。基本上,如果测试套件中的任何测试失败,则条形图为红色,如果全部通过,则为绿色。此外,对于JUnit,还有蓝色用于显示断言错误的单个测试。
最后,有什么好的起点吗?任何教程,显示使用Junit的文章
我很确定很快会在答案中出现多个这样的问题,只需坚持下去:)
答案 1 :(得分:1)
你会写一个测试课。
public class OracleMatchesSqlServer extends TestCase {
public void testHeadIdentifiersShouldBeEqual() throws Exception {
String head = "whatever your head should be";
IdentifierBean originalBean = YourClass.getHeadIdentifiers_old(head);
IdentifierBean oracleBean = YourClass.getHeadIdentifiers(head);
assertEquals(originalBean, oracleBean);
}
}
您可能会发现需要在头上参数化;这很简单。
更新:看起来像这样:
public class OracleMatchesSqlServer extends TestCase {
public void testHeadIdentifiersShouldBeEqual() throws Exception {
compareIdentifiersWithHead("head1");
compareIdentifiersWithHead("head2");
compareIdentifiersWithHead("etc");
}
private static void compareIdentifiersWithHead(String head) {
IdentifierBean originalBean = YourClass.getHeadIdentifiers_old(head);
IdentifierBean oracleBean = YourClass.getHeadIdentifiers(head);
assertEquals(originalBean, oracleBean);
}
}
* Is this a good approach?
不确定
* I will have multiple DAOs. Do I write the test methods inside the DAO itself or for each DAO I should have a separate JUnit Test Class?
为每个DAO使用单独的测试类进行尝试;如果这太繁琐了,那就试试另一种方式,看看你最喜欢什么。拥有单独测试类的细粒度可能更有帮助,但您的里程可能会有所不同。
* (might be n00b question) will all the test cases be run automatically? I do not want to go to the front end click bunch of stuff so that call to the DAO gets triggered.
根据您的环境,可以自动运行所有测试。
* when tests are ran will I find out which methods failed? and for the ones failed will it tell me the test method that failed?
是的,是的。
* lastly, any good starting points? any tutorials, articles that show working with Junit
我真的很喜欢Dave Astels'book。
答案 2 :(得分:0)
这是一个快速但相当彻底的intro to JUnit。
答案 3 :(得分:0)
编写和维护大型单元测试套件的另一个有用的介绍可能是本书(部分可在线获取):
XUnit Test Patterns, Refactoring Test Code by Gerard Meszaros
这本书分为三个主要部分。第一部分包含一系列介绍性叙述,描述了使用xUnit进行测试自动化的一些方面。第二部分描述了一些“测试气味”,它们是我们如何自动化测试的问题的症状。第三部分包含对模式的描述。