Asserts in java example

Java Assertions

Assertions in Java help to detect bugs by testing code we assume to be true.

An assertion is made using the assert keyword.

Here, condition is a boolean expression that we assume to be true when the program executes.

Enabling Assertions

By default, assertions are disabled and ignored at runtime.

To enable assertions, we use:

java -enableassertions:arguments

When assertions are enabled and the condition is true , the program executes normally.

But if the condition evaluates to false while assertions are enabled, JVM throws an AssertionError , and the program stops immediately.

Example 1: Java assertion

class Main < public static void main(String args[]) < String[] weekends = ; assert weekends.length == 2; System.out.println("There are " + weekends.length + " weekends in a week"); > > 
There are 3 weekends in a week 

We get the above output because this program has no compilation errors and by default, assertions are disabled.

After enabling assertions, we get the following output:

Exception in thread "main" java.lang.AssertionError 

Another form of assertion statement

assert condition : expression; 

In this form of assertion statement, an expression is passed to the constructor of the AssertionError object. This expression has a value that is displayed as the error’s detail message if the condition is false .

The detailed message is used to capture and transmit the information of the assertion failure to help in debugging the problem.

Example 2: Java assertion with expression example

class Main < public static void main(String args[]) < String[] weekends = ; assert weekends.length==2 : "There are only 2 weekends in a week"; System.out.println("There are " + weekends.length + " weekends in a week"); > > 
Exception in thread "main" java.lang.AssertionError: There are only 2 weekends in a week 

As we see from the above example, the expression is passed to the constructor of the AssertionError object. If our assumption is false and assertions are enabled, an exception is thrown with an appropriate message.

This message helps in diagnosing and fixing the error that caused the assertion to fail.

Enabling assertion for specific classes and packages

If we do not provide any arguments to the assertion command-line switches,

This enables assertions in all classes except system classes.

We can also enable assertion for specific classes and packages using arguments. The arguments that can be provided to these command-line switches are:

Читайте также:  Восстановить удаленные файлы html

Enable assertion in class names

To enable assertion for all classes of our program Main,

This enables assertion in only the AnimalClass in the Main program.

Enable assertion in package names

To enable assertions for package com.animal and its sub-packages only,

Enable assertion in unnamed packages

To enable assertion in unnamed packages (when we don’t use a package statement) in the current working directory.

Enable assertion in system classes

To enable assertion in system classes, we use a different command-line switch:

java -enablesystemassertions:arguments

The arguments that can be provided to these switches are the same.

Disabling Assertions

To disable assertions, we use:

java -disableassertions arguments 

To disable assertion in system classes, we use:

java -disablesystemassertions:arguments

The arguments that can be passed while disabling assertions are the same as while enabling them.

Advantages of Assertion

  1. Quick and efficient for detecting and correcting bugs.
  2. Assertion checks are done only during development and testing. They are automatically removed in the production code at runtime so that it won’t slow the execution of the program.
  3. It helps remove boilerplate code and make code more readable.
  4. Refactors and optimizes code with increased confidence that it functions correctly.

When to use Assertions

1. Unreachable codes

Unreachable codes are codes that do not execute when we try to run the program. Use assertions to make sure unreachable codes are actually unreachable.

void unreachableCodeMethod() < System.out.println("Reachable code"); return; // Unreachable code System.out.println("Unreachable code"); assert false; >

Let’s take another example of a switch statement without a default case.

The above switch statement indicates that the days of the week can be only one of the above 7 values. Having no default case means that the programmer believes that one of these cases will always be executed.

However, there might be some cases that have not yet been considered where the assumption is actually false.

This assumption should be checked using an assertion to make sure that the default switch case is not reached.

default: assert false: dayofWeek + " is invalid day"; 

If dayOfWeek has a value other than the valid days, an AssertionError is thrown.

2. Documenting assumptions

To document their underlying assumptions, many programmers use comments. Let’s take an example.

Comments can get out-of-date and out-of-sync as the program grows. However, we will be forced to update the assert statements; otherwise, they might fail for valid conditions too.

When not to use Assertions

1. Argument checking in public methods

Arguments in public methods may be provided by the user.

Читайте также:  Адаптивная верстка на FLEX CSS

So, if an assertion is used to check these arguments, the conditions may fail and result in AssertionError .

Instead of using assertions, let it result in the appropriate runtime exceptions and handle these exceptions.

2. To evaluate expressions that affect the program operation

Do not call methods or evaluate exceptions that can later affect the program operation in assertion conditions.

Let us take an example of a list weekdays which contains the names of all the days in a week.

 ArrayList weekdays = new ArrayList<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" )); ArrayList weekends= new ArrayList<>(Arrays.asList("Sunday", "Saturday" )); assert weekdays.removeAll(weekends); 

Here, we are trying to remove elements Saturday and Sunday from the ArrayList weekdays .

If the assertion is enabled, the program works fine. However, if assertions are disabled, the elements from the list are not removed. This may result in program failure.

Instead, assign the result to a variable and then use that variable for assertion.

ArrayList weekdays = new ArrayList<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" )); ArrayList weekends= new ArrayList<>(Arrays.asList("Sunday", "Saturday" )); boolean weekendsRemoved = weekdays.removeAll(weekends); assert weekendsRemoved; 

In this way, we can ensure that all the weekends are removed from the weekdays regardless of the assertion being enabled or disabled. As a result, it does not affect the program operation in the future.

Table of Contents

Источник

JUnit Assertions

Ассерты (asserts) — это специальные проверки , которые можно вставить в разные места кода. Их задача определять, что что-то пошло не так. Вернее, проверять, что все идет как нужно. Вот это “как нужно” они и позволяют задать различными способами.

С некоторыми ассертами ты уже сталкивался в коде выше. Первый из них – проверка объектов на равенство. Если объекты не равны — кинется исключение и тест будет провален.

Тут важен порядок сравнения , ведь JUnit в итоговом отчете напишет что-то типа “получено значение 1, а ожидалось 3”. Общий формат такой проверки имеет вид:

assertEquals(эталон, значение)
 @Test public void whenAssertingEquality ()

6.2 Методы assertEquals, assertTrue, assertFalse

Ниже я приведу список самых популярных методов — ассертов. По их названиям вполне можно догадаться как они работают. Но все же напишу краткое пояснение:

assertEquals Проверяет, что два объекта равны
assertArrayEquals Проверяет, что два массива содержат равные значения
assertNotNull Проверяет, что аргумент не равен null
assertNull Проверяет, что аргумент равен null
assertNotSame Проверят, что два аргумента — это не один и тот же объект
assertSame Проверят, что два аргумента — это один и тот же объект
assertTrue Проверяет, что аргумент равен true
assertFalse Проверяет, что аргумент равен false

Некоторые из этих методов кажутся излишними. Зачем использовать assertSame(a, b) , если можно просто написать assertTrue(a == b) ?

Читайте также:  Удалить два последних элемента массива php

Все дело в том, что assert — это очень умный метод. Он делает много чего полезного и, в том числе, пишет в лог информацию об ошибке . В первом случае он напишет, что ожидался объект А, а получен объект Б. Во втором случае просто напишет, что ожидалось true .

Когда у тебя сотни тестов, особенно выполняемые на специальном тестовом сервере, то наличие детальных логов может быть суперполезным. Думаю,ты понимаешь, о чем я.

Пример сравнения массивов:

 @Test public void whenAssertingArraysEquality() < char[] expected = ; char[] actual = "Junit".toCharArray(); assertArrayEquals(expected, actual); > 

6.3 Метод assertAll

Как уже говорилось выше, метод assert не просто выполняет проверку, но и пишет в лог много информации о сравнимых объектах.

Допустим выполняется сравнение:

 Address address = unitUnderTest.methodUnderTest(); assertEquals("Вашингтон", address.getCity()); assertEquals("Oracle Parkway", address.getStreet()); assertEquals("500", address.getNumber()); 

Но если один из параметров не совпадет, то проверки остальных не произойдет. А хотелось бы чтобы они все-таки произошли и их результаты записались в лог. Но при этом, если хотя бы одна проверка не прошла, то тест все-таки был провален.

Для этого есть специальный метод — assertAll() . В качестве первого аргумента он принимает комментарий, который нужно записать в лог, а дальше — любое количество функций-ассертов.

Вот как будет переписан наш пример с его помощью:

 Address address = unitUnderTest.methodUnderTest(); assertAll("Сложный сценарий сравнение адреса", () -> assertEquals("Вашингтон", address.getCity()), () -> assertEquals("Oracle Parkway", address.getStreet()), () -> assertEquals("500", address.getNumber()) ); 

Тогда если адрес будет неправильный, в лог будет написано что-то типа:

 Сложный сценарий сравнение адреса (3 failures) expected: but was: expected: but was: expected: but was:

6.4 Метод assertTimeout

Помнишь аннотацию @Timeout ? Она позволяла контролировать время выполнения всего метода. Но иногда бывает полезно задать ограничения на выполнения некоторой части кода внутри метода. Для этого можно использовать assertTimeout() .

В качестве первого параметра в него передается время, а в качестве второго — код (функция), который должен выполниться за указанное время. Пример:

 @Test public void whenAssertingTimeout() < assertTimeout( ofSeconds(2), () -> < // пауза в одну секунду Thread.sleep(1000); >); > 

У класса Assert есть 12 вариантов метода assertTimeout() . Если хочешь ознакомиться с ними подробнее, добро пожаловать в официальную документацию.

6.5 Метод assertThrows

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

На этот случай есть еще один полезный метод assert — это assertThrows() . Общий формат его вызова имеет вид:

 assertThrows(исключение, код)

По сути, он очень похож на метод assertTimeout() , только он проверяет, чтобы указанный код выкинул нужное исключение. Пример:

 @Test void whenAssertingException() < Throwable exception = assertThrows( IllegalArgumentException.class, () -> < throw new IllegalArgumentException("Exception message"); >); assertEquals("Exception message", exception.getMessage()); > 

Источник

Оцените статью