Skip to content

13 «Исключительные ситуации и их обработка. Тестирование исключений»

Notifications You must be signed in to change notification settings

levvolkov/exceptionSituations

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

13. Домашнее задание к занятию «Исключительные ситуации и их обработка. Тестирование исключений»

Цель задания

  1. Научиться добавлять логику исключений в приложение.
  2. Научиться тестировать логику исключений в приложении.

Инструкция к заданию

  1. Скачайте и установите профессиональный редактор кода Intellij Idea Community Version.
  2. Откройте IDEA, создайте и настройте новый Maven-проект (под каждую задачу следует создавать отдельный проект, если обратное не сказано в условии).
  3. Создайте пустой репозиторий на GitHub и свяжите его с папкой вашего проекта (не с какой-либо другой папкой).
  4. Правильно настройте репозиторий в плане .gitignore. Проигнорируйте папки .idea и target (раньше была out) и .iml-файл — их в репозитории быть не должно.
  5. Закоммитьте и запушьте созданный проект на GitHub, настройте GitHub Actions, сделайте git pull.
  6. Выполните в IDEA требуемую задачу согласно условию.
  7. Проверьте соблюдение правил форматирования кода.
  8. Убедитесь, что при запуске mvn clean verify (раньше было mvn clean test) все тесты запускаются, проходят, а сборка завершается успешно.
  9. Закоммитьте и отправьте в репозиторий содержимое папки проекта.
  10. Убедитесь, что CI запустился на последнем коммите и завершился успешно (зелёная галочка).

Материалы для выполнения задания

  1. Как создать Maven-проект в IDEA.
  2. Как отформатировать код в Java.
  3. Как настроить CI на основе GitHub Actions.

Задание 1 (обязательное)

Представим себе репозиторий, хранящий товары.

Товары будут описываться классом Product:

public class Product {
    protected int id;
    protected String title;
    protected int price;

    public Product(int id, String title, int price) {
        this.id = id;
        this.title = title;
        this.price = price;
    }
    
    // Вспомогательные методы для корректной работы equals
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Product product = (Product) o;
        return id == product.id && price == product.price && title.equals(product.title);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, title, price);
    }
    
    // геттеры + сеттеры
    // на id только геттер — пусть будет неизменяемым для товара
}

И репозиторий:

public class ShopRepository {
    private Product[] products = new Product[0];

    /**
     * Вспомогательный метод для имитации добавления элемента в массив
     * @param current — массив, в который мы хотим добавить элемент
     * @param product — элемент, который мы хотим добавить
     * @return — возвращает новый массив, который выглядит, как тот, что мы передали,
     * но с добавлением нового элемента в конец
     */
    private Product[] addToArray(Product[] current, Product product) {
        Product[] tmp = new Product[current.length + 1];
        for (int i = 0; i < current.length; i++) {
            tmp[i] = current[i];
        }
        tmp[tmp.length - 1] = product;
        return tmp;
    }

    /**
     * Метод добавления товара в репозиторий
     * @param product — добавляемый товар
     */
    public void add(Product product) {
        products = addToArray(products, product);
    }

    public Product[] findAll() {
        return products;
    }

    // Этот способ мы рассматривали в теории в теме про композицию
    public void remove(int id) {
        Product[] tmp = new Product[products.length - 1];
        int copyToIndex = 0;
        for (Product product : products) {
            if (product.getId() != id) {
                tmp[copyToIndex] = product;
                copyToIndex++;
            }
        }
        products = tmp;
    }
}

Вы решили сделать так, чтобы при попытке удаления несуществующего объекта из репозитория генерировалось ваше исключение, а не ArrayIndexOfBoundsException.

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

Что нужно сделать

  1. Создайте класс исключения NotFoundException, отнаследовавшись от RuntimeException, и реализуйте как минимум конструктор с параметром-сообщением. Он будет просто вызывать суперконструктор предка (см. ниже).
  2. В методе удаления removeById сначала проверяйте, есть ли элемент. Для этого прямо из метода removeById вызывайте метод findById: если результат null, тогда выкидывайте исключение NotFoundException.
  3. Напишите два автотеста на репозиторий: первый должен проверять успешность удаления существующего элемента, второй — генерации NotFoundException при попытке удаления несуществующего элемента.

Конструктор вашего исключения должен выглядеть так:

	public NotFoundException(String s) {
		super(s);
	}

Для реализации этой логики вам понадобится добавить метод findById, предназначенный для поиска товара в репозитории по его ID. Так он должен принимать параметр ID искомого товара, пробегаться по всем товарам репозитория и сверять их ID с искомым, в случае совпадения делать return этого товара.

Если же, пробежав все товары репозитория, ни один подходящий найден не был, то есть цикл закончился без вызова return внутри него, то следует сделать return null.

Общая схема этого метода будет такой:

public Product findById(???) {
  for (???) {
    if (???) {
      return product;
    }
  }
  return null;
}

Убедитесь, что ваши автотесты проходят. Напоминаем, что проект должен быть на базе Maven, с подключёнными зависимостями и необходимыми плагинами.

Мы рекомендуем вам указывать в сообщении исключения: при удалении по какому конкретно ID было сгенерировано ваше исключение.

Простейший способ, как это можно сделать: "Element with id: " + id + " not found".


Задание 2* (необязательное)

В том же проекте и в той же ветке добавьте новую функциональность.

В методе добавления нового товара в репозиторий должна осуществляться проверка на то, что в нём уже нет товара, у которого бы совпадал ID с ID добавляемого товара. Если же такой есть, то должно выкидываться ваше исключение — AlreadyExistsException.

Напишите два автотеста на репозиторий: первый должен проверять успешность добавления элемента, второй — генерации AlreadyExistsException при попытке добавить элемент с повторяющимся ID.


Правила приёма работы

Прикреплена ссылка на публичный репозиторий с решением задачи.


Критерии оценки

  1. В каждом репозитории размещено содержимое папки проекта IDEA. Корнем репозитория должна быть именно папка проекта — не папка src (не папка, внутри которой лежит папка проекта); в корне репозитория должна лежать сразу папка src.
  2. Есть файл .gitignore, игнорирующий ненужные файлы и папки, которые должны отсутствовать в репозитории. Если они присутствуют — их нужно оттуда удалить.
  3. Программа соответствует всем требованиям из условия задачи.
  4. Программа использует только те инструменты языка, которые мы проходили или которые прямо разрешены условием задачи.
  5. Программа работает правильно на всех примерах из условия.
  6. Программный код отформатирован и соответствует пройденным требованиям к качеству кода.
  7. При запуске mvn clean verify тесты запускаются и проходят, а сборка завершается успешно.
  8. В репозитории настроен CI на основе GitHub Actions и он успешно прошёл на последнем коммите.
  9. Программа спроектирована достаточно логично и правильно, не противоречит общепринятым в производстве практикам и традициям.
  10. При наличии недочётов, в зависимости от их серьёзности и количества, работа может быть отправлена на доработку или принята; решение принимается на основе экспертной оценки работы.

About

13 «Исключительные ситуации и их обработка. Тестирование исключений»

Topics

Resources

Stars

Watchers

Forks

Languages