Thursday, 23 May 2013

Простые тесты в Java. Белый ящик. Статический внутренний класс.

Искал как бы по-быстрому написать простые тесты в Java, в итоге осмыслил и скомпоновал найденное в виде этой заметки.
Итак, у нас есть некий класс с функциональностью, которую мы хотим протестировать.
Более того, мы хотим использовать тестирование методом "белого ящика" (white-box). В чём отличие белого ящика от чёрного, можете спросить вы. Отличие в том, что мы знаем что внутри белого ящика и можем использовать эти знания для проверки внутренних состояний объекта. Для этого нам понадобиться добавить в наш класс статический вложенный класс (static nested class).

Вся прелесть как раз в том, что создавая объекты внешнего класса в методах внутреннего класса, мы можем получить доступ к приватным членам этого внешнего класса.

public class Foo {
    private int value;
    private Foo link;

    public Foo() {
        value = 10;
        link = null;
    }

    public Foo bar(int value) {
        this.value = value;
        return this;
    }

    private static class Test {

        public static void testConstructor() {
            Foo foo = new Foo();
            assert (foo.value == 10): "value != 10";
            assert (foo.link == null): "link is not null";
        }

        public static void testBar() {
            Foo foo = new Foo();
            assert (foo.bar(20) == foo): "returned reference is not itself";
            assert (foo.value == 20): "value haven't changed after calling method";
        }

        public static void main(String[] args) {
            Test.testConstructor();
            Test.testBar();
            System.out.println("OK");
        }
    }
}

Также создаём статический метод main внутри статического класса для запуска самих тестов.
При этом скомпилированный байт код будет разнесён по двум разным файлам Foo.class и Foo$Test.class и мы можем не включать файлы с тестами в боевую сборку.
Запустить тест можно следующим образом:
> java -ea Foo\$Test
где -ea (enable assertion) для выдачи исключений о невыполнении теста.