2015-02-16 7 views
-2

Ниже приведены мои коды, интерфейс MyQueue и тестер JUnit. Мой код, кажется, в порядке, но тест не сработал, хотя ошибки нет. Может ли кто-нибудь помочь мне разобраться? Спасибо :)JUnit тестирование ошибки Java

MyQueue интерфейс:

import java.util.*; 

public interface MyQueue { 
    void enqueue(int in); 

    int dequeue() throws NoSuchElementException; // throw exception if isEmpty() is true 

    int noItems(); // returns the number of items in the array 

    boolean isEmpty(); // true if queue is empty 

}

JUnit код тестер:

import java.util.*; 

import junit.framework.TestCase; 

public class CircularArrayQueueTest extends TestCase 
{ 

    private void checkSize(int length, MyQueue queue) 
    { 
     assertEquals("Queue has wrong number of elements", length, 
       queue.noItems()); 
     if(length == 0) 
      assertTrue("Queue should be empty", queue.isEmpty()); 
     else 
      assertTrue("Queue should not be empty", !queue.isEmpty()); 
    } 

    public void testSimple() 
    { 
     MyQueue queue = new CircularArrayQueue(); 
     checkSize(0, queue); 
     queue.enqueue(3); 
     checkSize(1, queue); 
     try 
     { 
      assertEquals("Dequeue returns wrong element", 3, queue.dequeue()); 
     } catch(NoSuchElementException e) 
     { 
      throw e; 
     } 
     checkSize(0, queue); 
    } 

    public void testMultiInput() 
    { 
     MyQueue queue = new CircularArrayQueue(); 
     for(int i = 0; i < 1000; ++i) 
     { 
      int r = (int)Math.round(Math.random()); 
      checkSize(0, queue); 
      queue.enqueue(r); 
      checkSize(1, queue); 
      assertEquals("Dequeue returns wrong element", r, queue.dequeue()); 
     } 

    } 

    public void testManyEnqueueDequeue() 
    { 
     CircularArrayQueue queue = new CircularArrayQueue(); 
     int cnt = 0; 
     for(int i = 0; i < 100000; ++i) 
     { 
      if(Math.random() > 0.5) 
      { 
       queue.enqueue(i); 
       cnt++; 
      } else 
      { 
       if(!queue.isEmpty()) 
       { 
        queue.dequeue(); 
        cnt--; 
       } 
      } 
      assertEquals("Correct number of items", cnt, queue.noItems()); 
     } 
    } 

    public void testLargeQueue() 
    { 
     MyQueue queue = new CircularArrayQueue(); 
     int[] r = new int[ 1000 ]; 
     for(int i = 0; i < r.length; ++i) 
     { 
      r[ i ] = (int)Math.round(Math.random()); 
      checkSize(i, queue); 
      queue.enqueue(r[ i ]); 
     } 
     for(int i = 0; i < r.length; ++i) 
     { 
      assertEquals("Dequeue returns wrong element", r[ i ], 
        queue.dequeue()); 
      checkSize(r.length - i - 1, queue); 
     } 
     for(int i = 0; i < r.length; ++i) 
     { 
      r[ i ] = (int)Math.round(Math.random()); 
      checkSize(i, queue); 
      queue.enqueue(r[ i ]); 
     } 
     for(int i = 0; i < r.length; ++i) 
     { 
      assertEquals("Dequeue returns wrong element", r[ i ], 
        queue.dequeue()); 
      checkSize(r.length - i - 1, queue); 
     } 
    } 

    public void testThrows() 
    { 
     MyQueue queue = new CircularArrayQueue(); 
     int[] r = new int[ 1000 ]; 
     for(int i = 0; i < r.length; ++i) 
     { 
      r[ i ] = (int)Math.round(Math.random()); 
      checkSize(i, queue); 
      queue.enqueue(r[ i ]); 
     } 
     for(int i = 0; i < r.length; ++i) 
     { 
      assertEquals("Dequeue returns wrong element", r[ i ], 
        queue.dequeue()); 
      checkSize(r.length - i - 1, queue); 
     } 
     boolean throwsCorrectly = false; 
     try 
     { 
      queue.dequeue(); 
     } catch(NoSuchElementException e) 
     { 
      throwsCorrectly = true; 
     } 
     assertTrue("Throws when dequeuing empty queue", throwsCorrectly); 
    } 


    public void testResize() 
    { 
     CircularArrayQueue queue = new CircularArrayQueue(); 
     assertTrue("Initial capacity too large", queue.getCapacityLeft() <= 1024); 
     for(int i = 0; i < 1000; ++i) 
     { 
      queue.enqueue(i); 
     } 
     int currentCapacity = queue.getCapacityLeft(); 
     while(currentCapacity > 0) 
     { 
      queue.enqueue(9); 
      currentCapacity--; 
      assertEquals("Array size should not change", currentCapacity, 
        queue.getCapacityLeft()); 
     } 
     assertTrue("Should have reached capacity", queue.getCapacityLeft() == 0); 
     queue.enqueue(42); 
     assertTrue("Should have resized array", 
       currentCapacity < queue.getCapacityLeft()); 
     currentCapacity = queue.getCapacityLeft(); 
     for(int i = 0; i < 100; ++i) 
     { 
      queue.enqueue(i); 
      currentCapacity--; 
      assertEquals("Resizing too often (inefficient)", currentCapacity, 
        queue.getCapacityLeft()); 
     } 
    } 
} 

Ниже мой собственный написанный код:

import java.util.NoSuchElementException; 

public class CircularArrayQueue implements MyQueue{ 

    private static final int capacity = 10;//Initial Capacity 
    private Integer[] Queue; 
    private final int count; // capacity 
    private int head = 0; 
    private int tail = 0; 

    // Creates an empty queue using the capacity. 
    public CircularArrayQueue(){ 
     count = capacity; 
     Queue = new Integer[count]; 
    } 

    // Adds the specified element to the tail of the queue, expanding 
    // the capacity of the queue array if necessary. 
    public void enqueue(int in) { 
     if(isFull()){ 
      expandCapacity(); 
     } 
      Queue[tail] = in; 
      tail = (tail + 1) % Queue.length; 
    } 


    // Creates a new array to store the contents of the queue with 
    // twice the capacity of the old one. 
    public void expandCapacity() { 
     Integer[] larger = ((Integer[]) (new Integer[Queue.length * 2])); 

     for (int scan=0; scan < Queue.length; scan++) { 
      larger[scan] = Queue[head]; 
      head = (head+1) % Queue.length; 
     } 
     head = 0; 
     tail = Queue.length - 1; 
     Queue = larger; 
    } 

    // Removes the element at the head of the queue and returns a 
    // reference to it. Throws an EmptyCollectionException if the 
    // queue is empty. 
    public int dequeue() throws NoSuchElementException { 
     int item; 
     if(isEmpty()){ 
      throw new NoSuchElementException(); 
     }else{ 
      item = Queue[head]; 
      Queue[head] = null; 
      head = (head + 1); 
     } 
     return item; 
    } 

    // Returns the number of elements currently in this queue. 
    public int noItems() { 
     if(tail > head) 
      return tail - head; 
     return count - head + tail; 
    } 

    // Returns true if this queue is empty and false otherwise. 
    public boolean isEmpty() { 
     return (tail == head) ? true : false; 
    } 

    public boolean isFull() { 
     int diff = tail - head; 
     if(diff == -1 || diff == (count -1)) 
      return true; 
     return false; 
    } 

    public int getCapacityLeft() { 
     if(isFull()){ 
      return 0; 
     }else{ 
      return count-noItems(); 
     } 
    } 

} 
+1

Несоблюдение какого сообщения об ошибке? –

+0

Для воспроизведения 'интерфейс MyQueue' отсутствует. –

+0

@ChristianHujer код обновлен с помощью интерфейса MyQueue. – Hilton

ответ

1

Когда вы» повторное создание очереди, head является 0, tail 0 и count является capacity и capacity 10.

noItems() в этом случае возвращает count - head + tail, который 10 - 0 + 0, поэтому для пустого queue в тесте testSimple(), noItems() возвращает 10 вместо ожидаемого 0.

Осмотрите сообщения об ошибках, которые вы получаете, они сообщают вам именно об этом. Например, вы получаете:

junit.framework.AssertionFailedError: Queue has wrong number of elements expected:<0> but was:<10> 
at ... 

Что вы пишете модульные тесты - это хорошо. Существует некоторый потенциал для дальнейшего улучшения ваших методов о том, что:

  • Написать тесты первых, на самом деле сделать Red-Green-Refactor цикла TDD следующий Дяди Боба трех законов Test-Driven Development.
  • Используйте JUnit 4 вместо JUnit 3.
  • Следуйте правилу с одним утверждением. Каждый тестовый пример должен содержать только одно логическое утверждение.
  • Использование BDD. Четко укажите «данное соглашение, когда действие, затем утверждение».
  • Напишите меньше методов. testLargeQueue() слишком длинный.
  • DRY - не повторяйте себя. Удалите избыточность. Например, в testLargeQueue() существует много избыточности.
  • try { foo(); } catch (NoSuchElementException e) { throw e; } - это то же самое, что и только foo();. Почему так сложно ... (in testSimple())
  • Согласие на сообщения assert на самом деле должно описывать ожидаемое (правильное) поведение, а не действительное (неправильное) поведение. Кроме того, соглашение больше не использует эти сообщения - имя тестового примера должно сказать это уже.
  • В вашем конкретном случае вы, возможно, захотите пойти на TestNG вместо JUnit. Для тестирования объектов, где тестовые случаи зависят от состояний, которые могут быть установлены в предыдущих тестовых случаях, TestNG намного превосходит JUnit. Обычно я использую JUnit, но в этом случае я действительно рекомендую использовать TestNG.
+0

Спасибо за консультацию. – Hilton

Смежные вопросы