Considere o seguinte domínio de aplicação.

Uma livraria tem livros (representados pela classe  Book). Um livro é constituído por um autor, título, preço e isbn e tem uma dada categoria. (representada pela classe Category). Os livros são guardados de forma persistente pela aplicação. A entidade BookstoreService representa a interface disponível para aceder ao repositório persistente de livros. Esta entidade define métodos que podem ser utilizados para aceder aos livros existentes e para criar novos livros no repositório persistente.

public interface BookstoreService {

    /**
     * Find the book with the given isbn.
     * 
     * @param isbn the isbn to search
     *
     * @throws ServiceUnavailableException if the repository is not available
     *
     * @return the book with the given isbn, null if there is no book with such isbn.
     */
    Book findBookByIsbn(String isbn) throws ServiceUnavailableException;

    /**
     * Search for {@link Book}s that meet the given {@link BookSearchCriteria}.
     * 
     * @param bookSearchCriteria the search criteria.
     *
     * @throws ServiceUnavailableException if the repository is not available
     *
     * @return list of books (never <code>null</code>).
     */
    List<Book> findBooks(SearchCriteria bookSearchCriteria) throws ServiceUnavailableException;

    /**
     * Find all the categories available.
     * 
     * @throws ServiceUnavailableException if the repository is not available
     *
     * @return list with all the categories (never <code>null</code>).
     */
    List<Category> findAllCategories() throws ServiceUnavailableException;

    /**
     * Store a book in the repository.
     * 
     * @throws ServiceUnavailableException if the repository is not available
     *
     * @param book the book to store. It cannot be null.
     */
    void addBook(Book book) throws ServiceUnavailableException;
}

A entidade Bookstore representa o ponto de entrada da aplicação e permite procurar livros de acordo com um determinado critério de procura (nome, título e preço) e adicionar livros ao repositório persistente de livros da aplicação. Internamente, esta classe utiliza a classe BookstoreServiceImpl (que concretiza a interface BookstoreService) para oferecer a funcionalidade pretendida. Assim, cada instância de Bookstore está associada uma instância de BookstoreService. Os dois métodos suportados por Bookstore têm a seguinte interface e funcionalidade:
  • public void addBook(Book b) throws CannotProcessRequestException - adiciona um livro ao repositório persistente através do BookstoreService associado ao Bookstore. Caso a comunicação com o repositório persistente via BookstoreService falhe (este lançará a excepção ServiceUnavailableException), então este método lançará a excepção CannotProcessRequestException. Caso o livro a criar seja a referência nula, o BookstoreService já não é invocado e é lançado a excepção NullPointerException.
  • List<Book> finbBooks(String author, String title, BigDecimal price) throws CannotProcessRequestException - devolve a lista de livros presentes no repositório que verifica o critério de procura. O critério de procura pode incluir o nome do autor e/ou título. Adicionalmente, é possível indicar um preço máximo. Caso seja indicado um preço, então são removidos todos os livros com um preço maior da lista de livros retornados através da instância de BookstoreService associada a este Bookstore. Se não houver nenhum livro que obedeça ao critério de procura, então deve ser devolvido null. Caso o BookstoreService associado a este Bookstore não consiga contactar com o repositório, então deverá lançar a excepção CannotProcessRequestException.
O código da aplicação está disponível neste no seguinte projecto mavenbookstore.tgz. Este arquivo contém o código fonte da aplicação e ainda um esqueleto da classe de teste a desenvolver. A classe Bookstore tem vários erros. Os seus testes devem encontrá-los.
Utilizando a framework JMockit, verifique a correcta concretização dos método addBook e findBooks de Bookstore independentemente do código de BookstoreServiceImpl.
Depois de ter realizado os testes pode comparar a sua solução com a seguinte concretização da classe de teste: BookstoreTest.java