在java/junit中组织单元测试,以便使用公共api测试类
我正在实现一些基本的排序算法(为了学习),并想为它们编写单元测试在java/junit中组织单元测试,以便使用公共api测试类,java,junit,organization,Java,Junit,Organization,我正在实现一些基本的排序算法(为了学习),并想为它们编写单元测试 ... public static void sort(Comparable[] a); ... public static boolean isSorted(Comparable[] a); ... public static boolean isSorted(Comparable[] a),int from ,int to; ... 因此,我编写了以下测试来测试SelectionSort中的isSorted()方法 publ
...
public static void sort(Comparable[] a);
...
public static boolean isSorted(Comparable[] a);
...
public static boolean isSorted(Comparable[] a),int from ,int to;
...
因此,我编写了以下测试来测试SelectionSort中的isSorted()方法
public class SelectionSortTests {
String[] a ;
@After
public void tearDown() throws Exception {
a = null;
}
@Test
public void arraySortedSingleElement(){
a = new String[]{"A"};
Assert.assertTrue(SelectionSort.isSorted(a));
}
@Test
public void arraySortedDistinctElements(){
a = new String[]{"A","B","C","D"};
Assert.assertTrue(SelectionSort.isSorted(a));
}
@Test
public void arrayNotSorted(){
a = new String[]{"A","B","C","B"};
Assert.assertFalse(SelectionSort.isSorted(a));
}
...
}
现在我觉得,如果我为InsertionSort、ShellSort等编写测试,它们看起来都是一样的。只有被测试的类的名称会改变
那么,我应该如何组织测试呢?一个套件是答案还是我可以使用反射做得更好?可能是编写一个驱动程序,我可以在其中添加要测试的类的名称列表,驱动程序通过将类名传递给它来调用运行公共单元测试
我意识到这是一种常见的情况。想知道如何在没有唾沫或胶带的情况下处理这个问题
更新:
感谢@BevinQ和@Matthew Farwell,我尝试使用参数化单元测试来解决这个问题。
使用反射调用静态方法。。
似乎有效:)但我认为它仍然可以重构以避免重复代码
@RunWith(Parameterized.class)
public class ParameterizedSortTests {
private Class classToTest;
private Method methodToTest;
public ParameterizedSortTests(String packageName,String classToTest) {
super();
try {
this.classToTest = Class.forName(packageName+"."+classToTest);
} catch (ClassNotFoundException e) {
System.out.println("failed to get class!!");
e.printStackTrace();
}
}
//method return collection of class names to be tested
@Parameterized.Parameters
public static List<Object[]> classesToTest(){
return Arrays.asList(new Object[][]{
{"elemsorts","SelectionSort"} ,
{"elemsorts","InsertionSort"}
});
}
public void setMethod(String method,Class...args){
try {
this.methodToTest = this.classToTest.getMethod(method, args);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
@Test
public void arrayIsSorted(){
setMethod("isSorted",Comparable[].class);
String[] a = new String[]{"A","B","C","D"};
Boolean arraySorted = null;
try {
arraySorted = (Boolean)this.methodToTest.invoke(null, new Object[]{a});
System.out.println(this.methodToTest+"returned :"+arraySorted);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
Assert.assertTrue(arraySorted);
}
@Test
public void arrayIsNotSorted(){
setMethod("isSorted",Comparable[].class);
String[] a = new String[]{"A","B","C","B"};
Boolean arraySorted = null;
try {
arraySorted = (Boolean)this.methodToTest.invoke(null, new Object[]{a});
System.out.println(this.methodToTest+"returned :"+arraySorted);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//System.out.println("arraySorted="+arraySorted);
Assert.assertFalse(arraySorted);
}
}
@RunWith(参数化的.class)
公共类参数化SortTests{
私有类类测试;
私有方法测试;
公共参数化SortTests(字符串packageName、字符串classToTest){
超级();
试一试{
this.classToTest=Class.forName(packageName+“+classToTest);
}catch(classnotfounde异常){
System.out.println(“未能获取类!!”;
e、 printStackTrace();
}
}
//方法返回要测试的类名集合
@参数化。参数化
公共静态列表classesToTest(){
返回Arrays.asList(新对象[][]{
{“elemsorts”,“SelectionSort”},
{“elemsorts”,“InsertionSort”}
});
}
公共void setMethod(字符串方法、类…参数){
试一试{
this.methodToTest=this.classToTest.getMethod(方法,args);
}捕获(安全异常e){
e、 printStackTrace();
}捕获(无此方法例外){
e、 printStackTrace();
}
}
@试验
公共无效数组排序(){
setMethod(“isSorted”,可比[]类);
字符串[]a=新字符串[]{“a”、“B”、“C”、“D”};
布尔数组排序=null;
试一试{
arraySorted=(布尔)this.methodToTest.invoke(null,新对象[]{a});
System.out.println(this.methodToTest+“返回:”+arraySorted);
}捕获(IllegalArgumentException e){
e、 printStackTrace();
}捕获(非法访问例外e){
e、 printStackTrace();
}捕获(调用TargetException e){
e、 printStackTrace();
}
Assert.assertTrue(arraySorted);
}
@试验
公共无效数组未排序(){
setMethod(“isSorted”,可比[]类);
字符串[]a=新字符串[]{“a”、“B”、“C”、“B”};
布尔数组排序=null;
试一试{
arraySorted=(布尔)this.methodToTest.invoke(null,新对象[]{a});
System.out.println(this.methodToTest+“返回:”+arraySorted);
}捕获(IllegalArgumentException e){
e、 printStackTrace();
}捕获(非法访问例外e){
e、 printStackTrace();
}捕获(调用TargetException e){
e、 printStackTrace();
}
//System.out.println(“arraySorted=“+arraySorted”);
Assert.assertFalse(arraySorted);
}
}
为什么不做这样的事情
@Test
public void arraySortedDistinctElements(){
a = new String[]{"A","B","C","D"};
Assert.assertTrue(SelectionSort.isSorted(a));
Assert.assertTrue(InsertionSort.isSorted(a));
Assert.assertTrue(QuickSort.isSorted(a));
}
我不认为你有超过10种不同的分类需要测试。所以它应该是好的
另外,您可以在数组中声明所有排序类,并使用类属性进行加载。对于接口
public abstract class AbstractSortTests {
String[] a ;
@After
public void tearDown() throws Exception {
a = null;
}
protected abstract Sorter getSorter();
@Test
public void arraySortedSingleElement(){
a = new String[]{"A"};
Assert.assertTrue(getSorter().isSorted(a));
}
@Test
public void arraySortedDistinctElements(){
a = new String[]{"A","B","C","D"};
Assert.assertTrue(getSorter.isSorted(a));
}
...
}
public class SelectionSortTests extends AbstractSortTests {
protected Sorter getSorter(){
return SelectionSort.getInstance();
}
}
public class QuickSortTests extends AbstractSortTests {
protected Sorter getSorter(){
return QuickSort.getInstance();
}
}
使用反射,这是一个有点混乱,但仍然可以做到。我还没有测试过这段代码,所以可能已经测试过了
有几个bug,但在过去使用过这种方法。在99%的情况下,使用接口将是首选方法
public abstract class AbstractSortTests {
String[] a ;
@After
public void tearDown() throws Exception {
a = null;
}
protected abstract Sorter getSorter();
@Test
public void arraySortedSingleElement() throws Exception{
a = new String[]{"A"};
Assert.assertTrue(executeMethod(getSorterClass(), "isSorted", a);
}
@Test
public void arraySortedDistinctElements() throws Exception{
a = new String[]{"A","B","C","D"};
Assert.assertTrue(executeMethod(getSorterClass(), "isSorted", a);
}
private void executeMethod(Class<?> sortClass, String methodName, String[] values) throws Exception{
return sortClass.getDeclaredMethod(methodName, new Class[]{String[].class}).invoke(null, new Object[]{values});
}
...
}
public class SelectionSortTests extends AbstractSortTests {
protected Class<?> getSorterClass(){
return SelectionSort.class;
}
}
公共抽象类AbstractSortTests{
字符串[]a;
@之后
public void tearDown()引发异常{
a=零;
}
受保护的抽象分类器getSorter();
@试验
public void arraySortedSingleElement()引发异常{
a=新字符串[]{“a”};
Assert.assertTrue(executeMethod(getSortrClass(),“isSorted”,a);
}
@试验
public void ArraySortedDistincElements()引发异常{
a=新字符串[]{“a”、“B”、“C”、“D”};
Assert.assertTrue(executeMethod(getSortrClass(),“isSorted”,a);
}
私有void executeMethod(类sortClass、字符串methodName、字符串[]值)引发异常{
返回sortClass.getDeclaredMethod(methodName,新类[]{String[].Class}).invoke(null,新对象[]{values});
}
...
}
公共类SelectionSortTests扩展了AbstractSortTests{
受保护类GetSortrClass(){
返回SelectionSort.class;
}
}
正如@BevynQ所说的,如果你将方法变成非静态的,并且你实现了一个接口(下面称为Sorter
)
@RunWith(参数化的.class)
公共类分拣机{
@参数
公共静态可编辑数据(){
返回Arrays.asList(新对象[][]{
{new SelectionSort()},
{new BubbleSort()}
});
}
专用最终分拣机
公共分拣机测试(分拣机分拣机){
this.sorter=分拣机;
}
@试验
公共无效数组排序SingleElement(){
字符串[]a=新字符串[]{“a”};
Assert.assertTrue(sorter.isSorted(a));
}
@试验
public void arraysorteddinstinctelements(){
字符串[]a=新字符串[]{“a”、“B”、“C”、“D”};
Assert.assertTrue(sorter.isSorted(a));
}
@试验
public void arrayNotSorted(){
字符串[]a=新字符串[]{“a”、“B”、“C”、“B”};
Assert.assertFalse(sorter.isSorted(a));
@RunWith(Parameterized.class)
public class SorterTest {
@Parameters
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][] {
{ new SelectionSort() },
{ new BubbleSort() }
});
}
private final Sorter sorter
public SorterTest(Sorter sorter) {
this.sorter = sorter;
}
@Test
public void arraySortedSingleElement(){
String[] a = new String[]{"A"};
Assert.assertTrue(sorter.isSorted(a));
}
@Test
public void arraySortedDistinctElements(){
String[] a = new String[]{"A","B","C","D"};
Assert.assertTrue(sorter.isSorted(a));
}
@Test
public void arrayNotSorted(){
String[] a = new String[]{"A","B","C","B"};
Assert.assertFalse(sorter.isSorted(a));
}
}