Difference between revisions of "Tópicos sobre escrita de testes com JUnit/Album (JUnit example)"

From Wiki**3

< Tópicos sobre escrita de testes com JUnit
(Class Album)
 
(9 intermediate revisions by the same user not shown)
Line 4: Line 4:
 
Considere uma caderneta de cromos. Os cromos têm um número e uma imagem. Não é necessário modelar a imagem, considere a imagem como sendo uma instância da seguinte classe:
 
Considere uma caderneta de cromos. Os cromos têm um número e uma imagem. Não é necessário modelar a imagem, considere a imagem como sendo uma instância da seguinte classe:
  
<java5>
+
<source lang="java">
 
class Image { /* conteúdo omitido */ }
 
class Image { /* conteúdo omitido */ }
</java5>
+
</source>
  
 
A caderneta guarda os cromos pela ordem de numeração e não permite guardar cromos repetidos. É possível adicionar cromos a uma caderneta (método add) e é possível remover um cromo se for indicado o seu número (método remove). Duas cadernetas dizem-se iguais (equals) se tiverem o mesmo número de cromos (independentemente das características dos cromos individuais). É possível obter uma lista ordenada (por número) contendo os cromos de uma caderneta (método getAll).
 
A caderneta guarda os cromos pela ordem de numeração e não permite guardar cromos repetidos. É possível adicionar cromos a uma caderneta (método add) e é possível remover um cromo se for indicado o seu número (método remove). Duas cadernetas dizem-se iguais (equals) se tiverem o mesmo número de cromos (independentemente das características dos cromos individuais). É possível obter uma lista ordenada (por número) contendo os cromos de uma caderneta (método getAll).
Line 21: Line 21:
 
This is a very simple and uninteresting class.
 
This is a very simple and uninteresting class.
  
<java5>
+
<source lang="java">
 
public class Image {
 
public class Image {
  
 
}
 
}
</java5>
+
</source>
  
 
== Class Card ==
 
== Class Card ==
  
<java5>
+
<source lang="java">
</java5>
+
/**
 +
* The card class.
 +
*/
 +
public class Card implements Comparable<Card> {
 +
 
 +
    /**
 +
    * The card number.
 +
    */
 +
    private int _id;
 +
 
 +
    /**
 +
    * The image in this card.
 +
    */
 +
    private Image _image;
 +
 
 +
    /**
 +
    * How to initialise a new card.
 +
    *
 +
    * @param id
 +
    * @param image
 +
    */
 +
    public Card(int id, Image image) {
 +
        _id = id;
 +
        _image = image;
 +
    }
 +
 
 +
    /**
 +
    * @return the card number.
 +
    */
 +
    public int getId() {
 +
        return _id;
 +
    }
 +
   
 +
    /**
 +
    * @return image in this card.
 +
    */
 +
    public Image getImage() {
 +
        return _image;
 +
    }
 +
   
 +
    /**
 +
    * @see java.lang.Comparable#compareTo(java.lang.Object)
 +
    */
 +
    @Override
 +
    public int compareTo(Card other) {
 +
        return _id - other.getId();
 +
    }
 +
 
 +
}
 +
</source>
  
 
== Class Album ==
 
== Class Album ==
  
<java5>
+
<source lang="java">
 
import java.util.Collections;
 
import java.util.Collections;
 
import java.util.LinkedList;
 
import java.util.LinkedList;
Line 45: Line 94:
 
public class Album {
 
public class Album {
  
/**
+
    /**
* The card collection.
+
    * The card collection.
*/
+
    */
private TreeMap<Integer, Card> _cards = new TreeMap<Integer, Card>();
+
    private TreeMap<Integer, Card> _cards = new TreeMap<Integer, Card>();
  
/**
+
    /**
* @return sorted list (comparable cards).
+
    * @return sorted list (comparable cards).
*/
+
    */
public List<Card> getAll() {
+
    public List<Card> getAll() {
List<Card> lst = new LinkedList<Card>();
+
        List<Card> lst = new LinkedList<Card>();
lst.addAll(_cards.values());
+
        lst.addAll(_cards.values());
Collections.sort(lst);
+
        Collections.sort(lst);
return lst;
+
        return lst;
}
+
    }
  
/**
+
    /**
* Store a card. If a card has a number already in the tree, it replaces the
+
    * Store a card. If a card has a number already in the tree, it replaces the
* old one (alternatively, we could refuse storing a card with an existing
+
    * old one (alternatively, we could refuse storing a card with an existing
* number).
+
    * number).
*  
+
    *
* @param card
+
    * @param card
*/
+
    */
public void add(Card card) {
+
    public void add(Card card) {
_cards.put(card.getId(), card);
+
        _cards.put(card.getId(), card);
}
+
    }
  
/**
+
    /**
* Remove a card.
+
    * Remove a card.
*  
+
    *
* @param id
+
    * @param id
*            card number
+
    *            card number
*/
+
    */
public void remove(int id) {
+
    public void remove(int id) {
_cards.remove(id);
+
        _cards.remove(id);
}
+
    }
  
 +
    /**
 +
    * @return number of cards.
 +
    */
 +
    public int size() {
 +
        return _cards.size();
 +
    }
 +
   
 +
    /**
 +
    * @see java.lang.Object#equals(java.lang.Object)
 +
    */
 +
    @Override
 +
    public boolean equals(Object other) {
 +
        if (other instanceof Album) {
 +
            Album album = (Album)other;
 +
            return size() == album.size();
 +
        }
 +
        return false;
 +
    }
 
}
 
}
</java5>
+
</source>
 +
 
 +
== Class AlbumTest ==
 +
 
 +
A possible set of tests is as follows:
 +
<source lang="java">
 +
import junit.framework.Assert;
 +
import junit.framework.Test;
 +
import junit.framework.TestCase;
 +
import junit.framework.TestSuite;
 +
 
 +
/**
 +
*
 +
*/
 +
public class AlbumTest extends TestCase {
 +
    private Card _card;
 +
    private Album _album;
 +
 
 +
    /**
 +
    *
 +
    */
 +
    public AlbumTest() {
 +
        // nothing to do
 +
    }
 +
 
 +
    /**
 +
    * @param s
 +
    */
 +
    public AlbumTest(String s) {
 +
        super(s);
 +
    }
 +
 
 +
    /**
 +
    * All tests start with an album with a card in it.
 +
    *
 +
    * @see junit.framework.TestCase#setUp()
 +
    */
 +
    @Override
 +
    protected void setUp() {
 +
        _card = new Card(1, new Image());
 +
        _album = new Album();
 +
        _album.add(_card);
 +
    }
 +
 
 +
    /**
 +
    * Test equality.
 +
    */
 +
    public void testEquals() {
 +
        Card card = new Card(1, new Image());
 +
        Album album = new Album();
 +
        album.add(card);
 +
 
 +
        Assert.assertFalse(_album.equals(null));
 +
        Assert.assertNotSame(_album, album);
 +
        Assert.assertEquals(_album, album);
 +
        Assert.assertEquals(album, _album);
 +
    }
 +
 
 +
    /**
 +
    * Test insertion.
 +
    * Expensive: should be done some other way.
 +
    */
 +
    public void testInsertion() {
 +
        Card card = new Card(1, new Image());
 +
        Album album = new Album();
 +
        album.add(card);
 +
        Assert.assertSame(card, album.getAll().get(0));
 +
    }
 +
 
 +
}
 +
</source>
  
 
= How to Compile and Execute =
 
= How to Compile and Execute =
Line 88: Line 225:
 
== Compilation ==
 
== Compilation ==
  
* javac Image.java
+
javac Image.java
* javac Card.java
+
javac Card.java
* javac Album.java
+
javac Album.java
* javac -cp /usr/share/java/junit.jar:. AlbumTest.java
+
javac -cp /usr/share/java/junit.jar:. AlbumTest.java
  
 
== Execution ==
 
== Execution ==
  
java -cp  /usr/share/java/junit.jar:. junit.textui.TestRunner AlbumTest
+
  java -cp  /usr/share/java/junit.jar:. junit.textui.TestRunner AlbumTest
 +
 
 +
Output:
 +
 
 +
..
 +
Time: 0.004
 +
 +
OK (2 tests)
  
[[category:OOP]]
+
[[category:Ensino]]
 +
[[category:PO]]
 +
[[category:PO Exemplos]]
 +
[[category:Java]]
 
[[category:JUnit]]
 
[[category:JUnit]]
[[category:Java]]
 
[[category:Teaching]]
 

Latest revision as of 21:05, 8 November 2018

Problema

Considere uma caderneta de cromos. Os cromos têm um número e uma imagem. Não é necessário modelar a imagem, considere a imagem como sendo uma instância da seguinte classe:

class Image { /* conteúdo omitido */ }

A caderneta guarda os cromos pela ordem de numeração e não permite guardar cromos repetidos. É possível adicionar cromos a uma caderneta (método add) e é possível remover um cromo se for indicado o seu número (método remove). Duas cadernetas dizem-se iguais (equals) se tiverem o mesmo número de cromos (independentemente das características dos cromos individuais). É possível obter uma lista ordenada (por número) contendo os cromos de uma caderneta (método getAll).

  1. Modele e implemente as classes dos cromos (Card) e da caderneta (Album) (pode utilizar classes do pacote de colecções do Java).
  2. Escreva uma classe de teste que contenha um teste
    • que verifique se a inserção de um cromo na caderneta funciona; e outro
    • que verifique as propriedades associadas ao método equals.

Solução

Class Image

This is a very simple and uninteresting class.

public class Image {

}

Class Card

/**
 * The card class.
 */
public class Card implements Comparable<Card> {

    /**
     * The card number.
     */
    private int _id;

    /**
     * The image in this card.
     */
    private Image _image;

    /**
     * How to initialise a new card.
     *
     * @param id
     * @param image
     */
    public Card(int id, Image image) {
        _id = id;
        _image = image;
    }

    /**
     * @return the card number.
     */
    public int getId() {
        return _id;
    }
    
    /**
     * @return image in this card.
     */
    public Image getImage() {
        return _image;
    }
    
    /**
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
    @Override
    public int compareTo(Card other) {
        return _id - other.getId();
    }

}

Class Album

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;

/**
 * An album is built around a tree map, so that card order can be used.
 */
public class Album {

    /**
     * The card collection.
     */
    private TreeMap<Integer, Card> _cards = new TreeMap<Integer, Card>();

    /**
     * @return sorted list (comparable cards).
     */
    public List<Card> getAll() {
        List<Card> lst = new LinkedList<Card>();
        lst.addAll(_cards.values());
        Collections.sort(lst);
        return lst;
    }

    /**
     * Store a card. If a card has a number already in the tree, it replaces the
     * old one (alternatively, we could refuse storing a card with an existing
     * number).
     *
     * @param card
     */
    public void add(Card card) {
        _cards.put(card.getId(), card);
    }

    /**
     * Remove a card.
     *
     * @param id
     *            card number
     */
    public void remove(int id) {
        _cards.remove(id);
    }

    /**
     * @return number of cards.
     */
    public int size() {
        return _cards.size();
    }
    
    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object other) {
        if (other instanceof Album) {
            Album album = (Album)other;
            return size() == album.size();
        }
        return false;
    }
}

Class AlbumTest

A possible set of tests is as follows:

import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 *
 */
public class AlbumTest extends TestCase {
    private Card _card;
    private Album _album;

    /**
     *
     */
    public AlbumTest() {
        // nothing to do
    }

    /**
     * @param s
     */
    public AlbumTest(String s) {
        super(s);
    }

    /**
     * All tests start with an album with a card in it.
     *
     * @see junit.framework.TestCase#setUp()
     */
    @Override
    protected void setUp() {
        _card = new Card(1, new Image());
        _album = new Album();
        _album.add(_card);
    }

    /**
     * Test equality.
     */
    public void testEquals() {
        Card card = new Card(1, new Image());
        Album album = new Album();
        album.add(card);

        Assert.assertFalse(_album.equals(null));
        Assert.assertNotSame(_album, album);
        Assert.assertEquals(_album, album);
        Assert.assertEquals(album, _album);
    }

    /**
     * Test insertion.
     * Expensive: should be done some other way.
     */
    public void testInsertion() {
        Card card = new Card(1, new Image());
        Album album = new Album();
        album.add(card);
        Assert.assertSame(card, album.getAll().get(0));
    }

}

How to Compile and Execute

Compilation

javac Image.java
javac Card.java
javac Album.java
javac -cp /usr/share/java/junit.jar:. AlbumTest.java

Execution

 java -cp  /usr/share/java/junit.jar:. junit.textui.TestRunner AlbumTest

Output:

..
Time: 0.004

OK (2 tests)