JUnit4: тестирование ожидаемого исключения

Я пытаюсь протестировать с помощью JUnit4 метод, вызывающий исключение. Вот фрагмент кода:

package unit_tests;

import org.junit.Test;
import calculator.*;

@Test(expected=CalcError.class)
public void testDivision() {
    Calculator myCalc = new Calculator(10, 0);
    myCalc.setOperation(Calculator.Operation_e.DIVIDE);
    myCalc.getResult();
}

Проблема со строкой @Test(expected=CalcError.class): я получаю следующую ошибку:

Class<CalcError> cannot be resolved to a type

Вот как определяется CalcError:

package calculator;

public class Calculator {
    public class CalcError extends Exception {
        // ...
    }

    public double getResult() throws CalcError {
        // ...
    }
}

Я не понимаю, почему CalcError не является типом, хотя модульные тесты находятся в пакете unit_tests, а калькулятор - в пакете calculator.

Что мне не хватает?


person Jérôme    schedule 02.12.2011    source источник
comment
Не могли бы вы изменить свой код, чтобы его можно было скомпилировать? 1. getResult выдает ErreurCalcul, но вы ожидаете CalcError 2. testDivision не имеет предложения throws в своей подписи, но вы ожидаете поймать CalcError исключение, которое проверяется   -  person szhem    schedule 02.12.2011
comment
@mijer ErreurCalcul по-французски означает CalcError, я думаю, что Жером переводил на лету...   -  person Matthew Farwell    schedule 02.12.2011
comment
@mijer: исправил ошибку. Мэтью был прав, я перевел на лету и пропустил это!   -  person Jérôme    schedule 02.12.2011


Ответы (5)


CalcError — это внутренний класс, поэтому вам нужно использовать

@Test(expected=Calculator.CalcError.class)

См. Вложенные классы.

РЕДАКТИРОВАТЬ: вам также нужно будет объявить тестовый метод как бросающий Calculator.CalcError:

@Test(expected=Calculator.CalcError.class)
public void testDivision() throws Calculator.CalcError {
    Calculator myCalc = new Calculator(10, 0);
    myCalc.setOperation(Calculator.Operation_e.DIVIDE);
    myCalc.getResult();
}

Это сделано для того, чтобы угодить компилятору, потому что Calculator.CalcError является проверенным исключением.

person Matthew Farwell    schedule 02.12.2011
comment
Я подумал об этом и попробовал, но потом все равно получаю ошибку в тесте на строку myCalc.getResult(); : Unhandled exception type Calculator.CalcError - person Jérôme; 02.12.2011
comment
Добавлены броски Calculator.CalcError для тестового метода. - person Matthew Farwell; 02.12.2011

CalcError является внутренним классом Calculator. Он не импортируется import calculator.*;. Вам нужно будет добавить import calculator.Calculator.CalcError или уточнить CalcError (expected=Calculator.CalcError.class).

person Heiko Schmitz    schedule 02.12.2011

Иметь публичные классы в качестве внутренних классов — не очень хорошая идея. Вы должны переместить это в отдельный файл. Вложенными должны быть только частные классы. Вероятно, вы могли бы получить доступ к классу Error, используя Calculator.CalcError.class, но я настоятельно не рекомендую этого делать.

Кроме того, я думаю, что JUnit не хватает возможностей обнаружения исключений, поскольку вы не можете установить сообщение. Я модульно тестирую исключения, перехватывая их, а затем вызывая Assert.fail после вызова метода, который должен вызывать исключение:

try {
    someMethod();
    Assert.fail("SomeException should have been thrown");
catch(SomeException se) {
}
person Pete    schedule 02.12.2011

Поскольку CalcError является внутренним классом для калькулятора, вам нужно ссылаться на него следующим образом.

@Test(expected=Calculator.CalcError.class)
public void testDivision() {
person Roger Lindsjö    schedule 02.12.2011

Поскольку это проверяемое исключение, вам нужно добавить throws Exception в сигнатуру метода, иначе компилятор будет жаловаться на исключение.

person Mark Rotteveel    schedule 02.12.2011