Автор оригинала: Pankaj Kumar.
Иногда мы хотим проверить наши методы на наличие исключений. Тестирование позволяет нам выполнять тестирование исключений с использованием expectedExceptions
и expectedExceptionsMessageRegExp
параметров @Test
аннотации.
Проверьте ожидаемые исключения
Допустим, у нас есть простой полезный метод для деления двух чисел.
package com.journaldev.exceptions; public class MathUtils { public int divide(int x, int y) { return x / y; } }
Мы знаем, что если мы попытаемся разделить число на 0, оно выдаст java.lang.Исключение ArithmeticException
с сообщением как /на ноль
.
Давайте напишем тестовый класс TestNG для проверки этого сценария исключения.
package com.journaldev.exceptions; import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; import org.testng.annotations.DataProvider; public class MathUtilsTest { @Test(dataProvider = "dp", expectedExceptions = {ArithmeticException.class }) public void f(Integer x, Integer y) { MathUtils mu = new MathUtils(); assertEquals(mu.divide(x, y), x / y); } @DataProvider public Object[][] dp() { return new Object[][] { new Object[] { 4, 0 } }; } }
Мы получаем следующий результат, когда выполняем вышеописанный тестовый класс.
[RemoteTestNG] detected TestNG version 6.14.3 PASSED: f(4, 0)
Если мы удалим атрибут expectedexception
из аннотации @Test
, то наш тестовый случай завершится ошибкой с сообщением ниже.
[RemoteTestNG] detected TestNG version 6.14.3 FAILED: f(4, 0) java.lang.ArithmeticException: / by zero at com.journaldev.exceptions.MathUtils.divide(MathUtils.java:6) at com.journaldev.exceptions.MathUtilsTest.f(MathUtilsTest.java:13)
expectedExceptions
принимает значение в виде массива классов, поэтому значение ниже тоже будет работать нормально.
expectedExceptions = {ArithmeticException.class, NullPointerException.class }
TestNG Тест expectedExceptionsMessageRegExp
Мы также можем расширить наш метод тестирования для поиска сообщений об исключениях. Аннотация теста expectedExceptionsMessageRegExp
использует регулярное выражение. Давайте рассмотрим несколько примеров того, как мы можем его использовать.
@Test(dataProvider = "dp", expectedExceptions= {ArithmeticException.class}, expectedExceptionsMessageRegExp="/ by zero") public void f(Integer x, Integer y) { MathUtils mu = new MathUtils(); assertEquals(mu.divide(x, y), x/y); }
Приведенный выше метод тестирования пройдет только в том случае, если будет выдано исключение ArithmeticException с точным сообщением “/на ноль”.
[RemoteTestNG] detected TestNG version 6.14.3 PASSED: f(4, 0)
Давайте изменим сообщение так, чтобы наш тест не удался.
@Test(dataProvider = "dp", expectedExceptions= {ArithmeticException.class}, expectedExceptionsMessageRegExp="by zero") public void f(Integer x, Integer y) { MathUtils mu = new MathUtils(); assertEquals(mu.divide(x, y), x/y); }
Наш тест завершится неудачей при следующем выводе на консоль.
[RemoteTestNG] detected TestNG version 6.14.3 FAILED: f(4, 0) org.testng.TestException: The exception was thrown with the wrong message: expected "by zero" but got "/ by zero" at org.testng.internal.ExpectedExceptionsHolder.wrongException(ExpectedExceptionsHolder.java:71)
Давайте посмотрим, как мы можем использовать обычное исключение, когда мы не уверены в точном сообщении об исключении.
@Test(dataProvider = "dp", expectedExceptions= {ArithmeticException.class}, expectedExceptionsMessageRegExp=".* by zero*.") public void f(Integer x, Integer y) { MathUtils mu = new MathUtils(); assertEquals(mu.divide(x, y), x/y); }
Этот тест пройдет, потому что регулярное выражение, предоставленное нами, будет соответствовать сообщению об исключении, которое будет выдано.