JUnit4 fail () здесь, но где pass ()?
есть fail() метод в библиотеке JUnit4. Мне это нравится, но испытываю недостаток pass() метод, который отсутствует в библиотеке. Почему это так?
я узнал, что я могу использовать assertTrue(true) вместо этого, но все еще выглядит нелогично.
@Test
public void testSetterForeignWord(){
try {
card.setForeignWord("");
fail();
} catch (IncorrectArgumentForSetter ex){
}
// assertTrue(true);
}
6 ответов:
пока тест не выдает исключение, он проходит, если ваш
@Testаннотация указывает ожидаемое исключение. Я полагаю, чтоpass()может бросить специальное исключение, которое JUnit всегда интерпретирует как прохождение, чтобы закоротить тест, но это будет идти вразрез с обычным дизайном тестов (т. е. предполагать успех и терпеть неудачу только в том случае, если утверждение терпит неудачу) и, если люди поняли, что предпочтительнее использоватьpass(), это значительно замедлит большой набор прохождения тесты (из-за накладных расходов на создание исключений). Неудачные тесты не должны быть нормой, так что это не имеет большого значения, если у них есть эти накладные расходы.обратите внимание, что ваш пример может быть переписан следующим образом:
@Test(expected=IncorrectArgumentForSetter.class) public void testSetterForeignWord("") throws Exception { card.setForeignWord(""); }кроме того, вы должны отдать предпочтение использованию стандартных исключений Java. Ваш
IncorrectArgumentForSetterнаверное, должен бытьIllegalArgumentException.
Я думаю, что этот вопрос нуждается в обновленном ответе, так как большинство ответов здесь довольно устарели.
во-первых, на вопрос ОП:
Я думаю, что его довольно хорошо принято, что введение концепции "ожидаемого исключения" в JUnit было плохим шагом, так как это исключение может быть поднято в любом месте, и оно пройдет тест. Это работает, если вы бросаете (и утверждаете) очень специфические для домена исключения, но я только бросаю такие исключения, когда работаю в коде, который должен быть абсолютно безупречным, --большинство API будут просто выбрасывать встроенные исключения, такие как
IllegalArgumentExceptionилиIllegalStateException. Если два вызова, которые вы делаете, могут потенциально вызвать эти исключения, то@ExpectedExceptionаннотация будет зеленый бар ваш тест, даже если его неправильная строка, которая бросает исключение!для этой ситуации я написал класс, который я уверен, что многие другие здесь написали, это
assertThrowsспособ:public class Exceptions { private Exceptions(){} public static void assertThrows(Class<? extends Exception> expectedException, Runnable actionThatShouldThrow){ try{ actionThatShouldThrow.run(); fail("expected action to throw " + expectedException.getSimpleName() + " but it did not."); } catch(Exception e){ if ( ! expectedException.isInstance(e)) { throw e; } } } }этот метод просто возвращается, если создается исключение, позволяющее выполнять дальнейшие утверждения/проверки в тесте.
с синтаксисом Java 8 ваш тест выглядит очень красиво. Ниже приведен один из самых простых тестов на нашей модели, которая использует метод:
@Test public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() { //setup AxisRange range = new AxisRange(0,100); //act Runnable act = () -> range.setLowerBound(200); //assert assertThrows(IllegalArgumentException.class, act); }эти тесты немного шаткие, потому что шаг" act " на самом деле не выполняет никаких действий, но я думаю, что смысл все еще довольно ясен.
есть также крошечная маленькая библиотека на maven под названием catch-exception что использует синтаксис в стиле mockito, чтобы убедиться, что исключения выбрасываются. Это выглядит красиво, но я не поклонник динамических прокси. Тем не менее, есть синтаксис настолько гладкий, что он остается заманчивым:
// given: an empty list List myList = new ArrayList(); // when: we try to get the first element of the list // then: catch the exception if any is thrown catchException(myList).get(1); // then: we expect an IndexOutOfBoundsException assert caughtException() instanceof IndexOutOfBoundsException;наконец, для ситуации, с которой я столкнулся, чтобы добраться до этой темы, есть способ игнорировать тесты, Если некоторые conidition встретились.
прямо сейчас я работаю над тем, чтобы некоторые DLL вызывались через Java native-library-loading-library под названием JNA, но наш сервер сборки в Ubuntu. Мне нравится пытаться управлять такого рода развитием с помощью тестов JUnit, хотя они на данный момент далеки от "единиц". То, что я хочу сделать, это запустить тест, если я нахожусь на локальной машине, но игнорировать тест, если мы находимся на ubuntu. JUnit 4 имеет положение для этого, называется
Assume:@Test public void when_asking_JNA_to_load_a_dll() throws URISyntaxException { //this line will cause the test to be branded as "ignored" when "isCircleCI" //(the machine running ubuntu is running this test) is true. Assume.assumeFalse(BootstrappingUtilities.isCircleCI()); //an ignored test will typically result in some qualifier being put on the results, //but will also not typically prevent a green-ton most platforms. //setup URL url = DLLTestFixture.class.getResource("USERDLL.dll"); String path = url.toURI().getPath(); path = path.substring(0, path.lastIndexOf("/")); //act NativeLibrary.addSearchPath("USERDLL", path); Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class); //assert assertThat(dll).isNotNull(); }
искал
passметод для JUnit, так что я мог бы закоротить некоторые тесты, которые не были применимы в некоторых сценариях (есть интеграционные тесты, а не чистые модульные тесты). Так что жаль, что его там нет.к счастью, есть способ, чтобы тест игнорировался условно, что на самом деле подходит еще лучше в моем случае с помощью
assumeTrueспособ:предположим.assumeTrue (isTestApplicable);
Так вот тест быть выполнена только при isTestApplicable правда, проверить, в противном случае будут игнорироваться.
нет необходимости в методе pass, потому что при отсутствии AssertionFailedException выбрасывается из тестового кода модульный тестовый случай пройдет.
метод fail () фактически вызывает AssertionFailedException для сбоя testCase, если управление доходит до этой точки.
Я думаю, что этот вопрос является результатом небольшого недопонимания процесса выполнения теста. В JUnit (и других инструментах тестирования) результаты подсчитываются для каждого метода, а не для вызова assert. Там нет счетчика, который отслеживает, сколько прошло / не прошло .
JUnit в выполнении каждого тестового метода в отдельности. Если метод возвращается успешно, то тест регистрируется как "пройденный". Если возникает исключение, то тест регистрируется как"failed". В последнем случае два ней возможны: 1) Вывод исключение утверждения, 2) Любой другой вид исключения. Статус будет " failed "в первом случае, и" error " во втором случае.
на
Assertкласс многие методы стенографии доступны для создания исключений утверждений. Другими словами,Assert- это уровень абстракции над исключениями JUnit.например, это исходный код
assertEqualson GitHub:/** * Asserts that two Strings are equal. */ static public void assertEquals(String message, String expected, String actual) { if (expected == null && actual == null) { return; } if (expected != null && expected.equals(actual)) { return; } String cleanMessage = message == null ? "" : message; throw new ComparisonFailure(cleanMessage, expected, actual); }как вы можете видите ли, в случае равенства ничего не происходит, иначе будет выброшено исключение.
так:
assertEqual("Oh!", "Some string", "Another string!");просто бросает!--7--> исключение, которое будет поймано JUnit, и
assertEqual("Oh?", "Same string", "Same string");ничего не делает.
в общем, что-то вроде
pass()не будет никакого смысла, потому что он ничего не сделал.
Comments