Тестирование на равенство Junit итерируемого
Я пытаюсь написать модульные тесты для BinarySearchTree
класс keys()
вернуть Iterable
.Он использует другой класс под названием Queue
в котором ключи поставлены в очередь и возвращены..
Очередь (сторонний класс), однако, не имеет равенства ().
public class BinarySearchTree<Key extends Comparable<Key>,Value> {
Node root ;
private class Node{
private Key key;
private Value val;
private Node left;
private Node right;
private int N;
public Node(Key k, Value v,int N) {
super();
this.key = k;
this.val = v;
this.N = N;
}
}
public Iterable<Key> keys(){
Queue<Key> q = new Queue<Key>();
inOrder(root,q);
return q;
}
private void inOrder(Node x,Queue q){
if(x == null)return;
inOrder(x.left,q);
q.enqueue(x.key);
inOrder(x.right,q);
}
...
}
пытаясь написать модульный тест
@Test
public void testKeys(){
MyBST<String, Integer> st = new MyBST<String, Integer>();
st.put("S",7);
st.put("E",2);
st.put("X",8);
st.put("A",3);
st.put("R",4);
st.put("C",1);
st.put("H",5);
st.put("M",6);
Queue<String> q = new Queue<String>();
q.enqueue("A");
q.enqueue("C");
q.enqueue("E");
q.enqueue("H");
q.enqueue("M");
q.enqueue("R");
q.enqueue("S");
q.enqueue("X");
Iterable<String> actual = st.keys();
assertEquals(q,actual);
}
Это не удается
java.lang.AssertionError: expected: std.Queue<A C E H M R S X > but was: std.Queue<A C E H M R S X >
at org.junit.Assert.fail(Assert.java:93)
at org.junit.Assert.failNotEquals(Assert.java:647)
at org.junit.Assert.assertEquals(Assert.java:128)
at org.junit.Assert.assertEquals(Assert.java:147)
at week4.MyBSTTests.testKeys(BSTTests.java:304)
Должен ли я реализовать метод equals() в стороннем классе или есть другой способ проверить это на равенство? Все, что я мог придумать, это запустить цикл удаления очереди из очереди q и сравнить его с тем, что возвратил итератор. Я не уверен, что есть лучший способ... Пожалуйста, посоветуйте...
Iterable<String> actual = st.keys();
Iterator<String> actualit = actual.iterator();
while(actualit.hasNext()){
String actualkey = actualit.next();
String exp = q.dequeue();
assertEquals(actualkey,exp);
}
3 ответа
Используйте Hamcrest's Matchers.contains
(описано здесь). Например:
assertThat(queue1.keys(), Matchers.contains("A", "C", "E", "H", "M", "R", "S", "X"));
Это проверит элементы, которые Iterable
возвращает без необходимости равенства, реализованного в вашем классе очереди.
Вы можете использовать служебный класс java.util.Arrays. Из того, что я помню, интерфейс Queue имеет метод toArray. Так было бы что-то вроде этого:
assertTrue(Arrays.equals(queue1.toArray(),queue2.toArray()));
Поскольку это сторонняя библиотека, вы можете использовать Apache Commons:
Object[] o = IteratorUtils.toArray(queue1.iterator());
Object[] o2 = IteratorUtils.toArray(queue1.iterator());
assertTrue(Arrays.equals(o,o2));
Вот как я это сделал.
Я преобразовал Iterable в ArrayList. Затем я сделал еще один массив ожидаемых ключевых значений. Таким образом, я могу проверить, равны ли два arrayList, используя assertEquals(arrayList1, arrayList2). Вот код, который я написал для тестирования моего метода обхода preOrder.
import static org.junit.Assert.*;
import java.util.ArrayList;
import org.junit.Test;
public class BSTTest
{
BST<Integer, String> binaryTree = new BST<Integer, String>();
@Test
public void preOrdertest()
{
binaryTree.put(87, "Orange");
binaryTree.put(77, "Black");
binaryTree.put(81, "Green");
binaryTree.put(89, "Blue");
binaryTree.put(4, "Yellow");
binaryTree.put(26, "white");
binaryTree.put(23, "Purple");
binaryTree.put(27, "Violet");
binaryTree.put(57, "red");
binaryTree.put(1, "crimson");
ArrayList<Integer> testList = new ArrayList<>();
testList.add(87);
testList.add(77);
testList.add(4);
testList.add(1);
testList.add(26);
testList.add(23);
testList.add(27);
testList.add(57);
testList.add(81);
testList.add(89);
Iterable<Integer> actual = binaryTree.preOrder();
ArrayList<Integer> actualList = new ArrayList<>();
if (actual != null)
{
for (Integer e : actual)
actualList.add(e);
}
assertEquals(testList, actualList);
}
}