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
 
(One intermediate revision 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">
 
/**
 
/**
 
  * The card class.
 
  * The card class.
Line 35: Line 35:
 
public class Card implements Comparable<Card> {
 
public class Card implements Comparable<Card> {
  
/**
+
    /**
* The card number.
+
    * The card number.
*/
+
    */
private int _id;
+
    private int _id;
  
/**
+
    /**
* The image in this card.
+
    * The image in this card.
*/
+
    */
private Image _image;
+
    private Image _image;
  
/**
+
    /**
* How to initialise a new card.
+
    * How to initialise a new card.
*  
+
    *
* @param id
+
    * @param id
* @param image
+
    * @param image
*/
+
    */
public Card(int id, Image image) {
+
    public Card(int id, Image image) {
_id = id;
+
        _id = id;
_image = image;
+
        _image = image;
}
+
    }
  
/**
+
    /**
* @return the card number.
+
    * @return the card number.
*/
+
    */
public int getId() {
+
    public int getId() {
return _id;
+
        return _id;
}
+
    }
+
   
/**
+
    /**
* @return image in this card.
+
    * @return image in this card.
*/
+
    */
public Image getImage() {
+
    public Image getImage() {
return _image;
+
        return _image;
}
+
    }
+
   
/**
+
    /**
* @see java.lang.Comparable#compareTo(java.lang.Object)
+
    * @see java.lang.Comparable#compareTo(java.lang.Object)
*/
+
    */
@Override
+
    @Override
public int compareTo(Card other) {
+
    public int compareTo(Card other) {
return _id - other.getId();
+
        return _id - other.getId();
}
+
    }
  
 
}
 
}
</java5>
+
</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 94: 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.
+
    * @return number of cards.
*/
+
    */
public int size() {
+
    public int size() {
return _cards.size();
+
        return _cards.size();
}
+
    }
+
   
/**
+
    /**
* @see java.lang.Object#equals(java.lang.Object)
+
    * @see java.lang.Object#equals(java.lang.Object)
*/
+
    */
@Override
+
    @Override
public boolean equals(Object other) {
+
    public boolean equals(Object other) {
if (other instanceof Album) {
+
        if (other instanceof Album) {
Album album = (Album)other;
+
            Album album = (Album)other;
return size() == album.size();
+
            return size() == album.size();
}
+
        }
return false;
+
        return false;
}
+
    }
 
}
 
}
</java5>
+
</source>
  
 
== Class AlbumTest ==
 
== Class AlbumTest ==
  
 
A possible set of tests is as follows:
 
A possible set of tests is as follows:
<java5>
+
<source lang="java">
 
import junit.framework.Assert;
 
import junit.framework.Assert;
 
import junit.framework.Test;
 
import junit.framework.Test;
Line 164: Line 164:
 
  */
 
  */
 
public class AlbumTest extends TestCase {
 
public class AlbumTest extends TestCase {
private Card _card;
+
    private Card _card;
private Album _album;
+
    private Album _album;
  
/**
+
    /**
*  
+
    *
*/
+
    */
public AlbumTest() {
+
    public AlbumTest() {
// nothing to do
+
        // nothing to do
}
+
    }
  
/**
+
    /**
* @param s
+
    * @param s
*/
+
    */
public AlbumTest(String s) {
+
    public AlbumTest(String s) {
super(s);
+
        super(s);
}
+
    }
  
/**
+
    /**
* All tests start with an album with a card in it.
+
    * All tests start with an album with a card in it.
*  
+
    *
* @see junit.framework.TestCase#setUp()
+
    * @see junit.framework.TestCase#setUp()
*/
+
    */
@Override
+
    @Override
protected void setUp() {
+
    protected void setUp() {
_card = new Card(1, new Image());
+
        _card = new Card(1, new Image());
_album = new Album();
+
        _album = new Album();
_album.add(_card);
+
        _album.add(_card);
}
+
    }
  
/**
+
    /**
* Test equality.
+
    * Test equality.
*/
+
    */
public void testEquals() {
+
    public void testEquals() {
Card card = new Card(1, new Image());
+
        Card card = new Card(1, new Image());
Album album = new Album();
+
        Album album = new Album();
album.add(card);
+
        album.add(card);
  
Assert.assertFalse(_album.equals(null));
+
        Assert.assertFalse(_album.equals(null));
Assert.assertNotSame(_album, album);
+
        Assert.assertNotSame(_album, album);
Assert.assertEquals(_album, album);
+
        Assert.assertEquals(_album, album);
Assert.assertEquals(album, _album);
+
        Assert.assertEquals(album, _album);
}
+
    }
  
/**
+
    /**
* Test insertion.
+
    * Test insertion.
* Expensive: should be done some other way.
+
    * Expensive: should be done some other way.
*/
+
    */
public void testInsertion() {
+
    public void testInsertion() {
Card card = new Card(1, new Image());
+
        Card card = new Card(1, new Image());
Album album = new Album();
+
        Album album = new Album();
album.add(card);
+
        album.add(card);
Assert.assertSame(card, album.getAll().get(0));
+
        Assert.assertSame(card, album.getAll().get(0));
}
+
    }
  
 
}
 
}
</java5>
+
</source>
  
 
= How to Compile and Execute =
 
= How to Compile and Execute =

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)