JUnit 예상되는 예외 테스트: @Test(예상)

⚡ 스마트 요약

JUnit 예외 테스트는 `@Test` 어노테이션의 선택적 `expected` 매개변수를 사용하여 메서드가 의도한 오류를 발생시키는지 확인합니다. JUnit 4 그리고 assertThrows 메서드는 JUnit 5.

  • 🔘 목적 : 잘못된 입력이 오답을 알려주는 대신, 문서에 명시된 예외를 발생시킨다는 것을 증명하십시오.
  • ☑️ 구문 : @Test(expected = ArithmeticException.class)는 정확히 해당 예외 유형이 발생했을 때만 통과합니다.
  • 예: JUnit메시지가 0으로 나누어지며, AirthematicTest는 그 결과로 ArithmeticException이 발생할 것으로 예상합니다.
  • 🧪 대안 : try 블록 다음에 fail()을 사용하면 예외를 검사한 후 해당 예외에 대해 어설션을 수행할 수 있습니다.
  • 🛠️ JUnit 5: assertThrows는 포착된 예외를 반환하므로 예외 메시지와 원인도 검증할 수 있습니다.
  • 📌 함정: 예외가 발생하는 곳에서는 예상 매개변수가 그대로 전달되므로 설정 코드의 오류를 숨길 수 있습니다.

JUnit @Test(expected) 매개변수를 사용한 예상 예외 테스트

JUnit 다음과 같은 시설을 제공합니다 trac예외를 발생시키고 코드가 예상한 예외를 발생시키는지 여부도 확인합니다.

JUnit 4는 예외 테스트를 위한 쉽고 읽기 쉬운 방법을 제공합니다. 다음을 사용할 수 있습니다.

  • 선택적 매개변수(예상) @테스트 어노테이션예산 및
  • 에 trac이 정보를 사용하려면 "fail()" 함수를 사용할 수 있습니다.

DaVinci에는 테스트 예외가 발생하면 해당 선택적 매개변수에 제공하는 예외 클래스가 올바른지 확인해야 합니다. @테스트 어노테이션 해당 메서드가 실제로 발생시키는 예외와 동일합니다. 이는 당신이 해당 메서드에서 예외가 발생할 것으로 예상하기 때문입니다. 단위 테스트그렇지 않으면 우리의 JUnit 테스트가 실패할 것입니다.

예시: @Test(expected = IllegalArgumentException.class)

"expected" 매개변수를 사용하면 테스트에서 발생할 수 있는 예외 이름을 지정할 수 있습니다. 위 예시에서는 "IllegalArgumentException이는 개발자가 허용되지 않는 인수를 사용할 경우 테스트에서 발생하는 오류입니다.

@Test(expected)를 사용한 예시

예외 테스트를 이해하기 위해 예시를 만들어 보겠습니다. Java 예외를 던지는 메서드를 가진 클래스 예외여러분은 테스트 클래스에서 이를 처리하고 테스트할 것입니다. 고려해 보세요. JUnitMessage.java 파일에는 수학 연산을 수행하는 메서드가 있습니다. 14번째 줄의 나눗셈은 0으로 나누기 때문에 해당 메서드는 항상 "ArithmeticException"을 발생시킵니다. 아래를 참조하세요.

JUnit메시지 클래스 Eclipse printMessage 함수가 14번째 줄에서 0으로 나누는 오류가 발생했습니다.

package guru99.junit;

public class JUnitMessage{

	private String message;

	public JUnitMessage(String message) {
		this.message = message;
	}

public void printMessage(){

	System.out.println(message); 
	int divide=1/0;

}

public String printHiMessage(){ 

	message="Hi!" + message;
	
	System.out.println(message);

	return message;
}

}

Code 설명 :

  • Code 7 라인 : 필드 초기화를 통해 매개변수화된 생성자를 생성합니다.
  • Code 11-14행: 수학 연산을 위한 메서드를 생성합니다.
  • Code 18 라인 : 메시지를 인쇄하는 다른 방법 만들기.
  • Code 20 라인 : 메시지를 인쇄하기 위해 새 문자열을 만듭니다.
  • Code 22 라인 : 20번째 줄에서 생성된 새 메시지를 출력합니다.

위 내용을 검증할 테스트 클래스를 만들어 보겠습니다. Java 예외를 확인하기 위한 클래스입니다.

아래는 위 코드에서 발생하는 예외(여기서는 ArithmeticException)를 단위 테스트하는 테스트 클래스입니다. Java 수업:

AirthematicTest.java

아래 스크린샷은 편집기에서 동일한 테스트를 보여주는 것으로, 파일은 AirthematicTest1로 저장되었으며 예상 매개변수는 13번째 줄에서 강조 표시되어 있습니다.

AirthematicTest1 클래스 Eclipse 13번째 줄에 있는 @Test(expected = ArithmeticException.class) 부분이 강조 표시되어 있습니다.

package guru99.junit;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class AirthematicTest {

	public String message = "Saurabh";
	
	JUnitMessage junitMessage = new JUnitMessage(message);
	
	@Test(expected = ArithmeticException.class)
	public void testJUnitMessage(){

		System.out.println("Junit Message is printing ");
		junitMessage.printMessage();

	}

	@Test
	public void testJUnitHiMessage(){ 
		message="Hi!" + message;
		System.out.println("Junit Message is printing ");
		assertEquals(message, junitMessage.printHiMessage());
	
	}
}

Code 설명 :

  • Code 13 라인 : @Test 어노테이션을 사용하여 테스트를 작성합니다. 위 클래스의 메서드를 실행하면 수학 연산이 수행됩니다. 여기서 ArithmeticException이 예상되므로 @Test 어노테이션에 ArithmeticException을 매개변수로 명시합니다.
  • Code 17 라인 : printMessage() 호출 JUnit메시지.java.
  • Code 21-22행: 이번에는 예상 매개변수 없이 "Hi" 메시지를 확인하는 또 다른 테스트 메서드를 생성합니다.

해당 클래스는 두 개의 테스트 메서드를 가지고 있으므로, 한 번 실행하면 두 메서드 모두 실행됩니다. 하나는 ArithmeticException을 예상하는 메서드이고, 다른 하나는 반환된 문자열을 검증하는 메서드입니다.

참고 : 이 예제는 원문에서 세 가지 이름으로 나타납니다. 코드 목록에서는 클래스 이름을 AirthematicTest로, 에디터 스크린샷에서는 AirthematicTest1로, 결과 화면에서는 JunitTestExample로 표시합니다. 코드는 모두 동일하며 파일 이름만 다릅니다.

실행해보고 결과를 확인해 보겠습니다. JUnit 아래 보고서는 실행 과정을 보여줍니다. JunitTestExample.java.

출력:

다음은 테스트가 실패 없이 성공적으로 완료되었음을 보여주는 출력 결과입니다. trace는 아래와 같습니다.

Eclipse JUnit JunitTestExample 실행 결과 2/2, 오류 및 실패 없음

두 방법 모두 통과했습니다. 첫 번째 방법은 선언된 ArithmeticException이 발생했기 때문에 통과했고, 두 번째 방법은 반환된 문자열이 일치했기 때문에 통과했습니다. 만약 나눗셈에서 예외가 발생하지 않았다면, JUnit 첫 번째 방법은 "예상 예외: java.lang.ArithmeticException"이라는 메시지와 함께 실패했을 것입니다.

예외를 테스트하는 세 가지 방법 JUnit 4

예상되는 매개변수는 세 개 중 가장 짧습니다. JUnit 네 가지 관용구가 있지만, 항상 옳은 것은 아닙니다. 표는 선택을 결정하는 두 가지 질문, 즉 메시지에 대해 확신을 가질 수 있는지, 그리고 어떤 표현이 사용되었는지 아는지에 따라 각 관용구를 비교합니다.

접근 메시지를 주장하는 건가요? 던지는 줄을 고정시키나요? 가장 좋은
@Test(expected = X.class) 아니 아니요, 메서드 내의 어느 줄에서든 예외가 발생할 수 있습니다. 예외 유형만 중요한 간단한 테스트입니다.
시도/실패()/캐치 네, 캐치 블록 안쪽에 있습니다. 네, 감시 대상 통화만 감시됩니다. 메시지 또는 원인을 검사해야 하는 테스트.
@규칙 예상 예외 네, expectMessage()를 통해 가능합니다. 아니 기존 시스템은 이미 규칙에 기반하여 구축되었습니다.

서론에서 언급된 fail() 관용구는 다음과 같습니다. 호출에서 예외가 발생하지 않으면 fail()이 실행되고 테스트는 작성하신 메시지를 보고합니다.

@Test
public void testDivideByZero() {
    try {
        junitMessage.printMessage();
        fail("Expected an ArithmeticException");
    } catch (ArithmeticException e) {
        assertEquals("/ by zero", e.getMessage());
    }
}

ExpectedException 규칙은 이 둘 사이에 위치합니다. 이 규칙은 더 이상 사용되지 않도록 권장됩니다. JUnit 4.13 버전에서는 다음에 설명할 assertThrows 메서드를 선호하므로 새로운 버전이 나왔습니다. JUnit 4가지 테스트에서는 이를 채택해서는 안 됩니다.

예외를 테스트하는 방법 JUnit assertThrows()를 사용한 5번째

JUnit 5는 @Test에서 예상되는 매개변수를 완전히 제거합니다. Jupiter는 제공합니다. assertThrows()이 함수는 예외 클래스와 테스트 대상 코드를 담고 있는 람다 함수를 인수로 받습니다. 이 함수는 포착된 예외를 반환하므로, 예외 메시지, 예외 원인 및 사용자 정의 필드를 이후에 검증할 수 있습니다.

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;

public class AirthematicJupiterTest {

    JUnitMessage junitMessage = new JUnitMessage("Saurabh");

    @Test
    public void testJUnitMessage() {
        ArithmeticException thrown = assertThrows(
                ArithmeticException.class,
                () -> junitMessage.printMessage());
        assertEquals("/ by zero", thrown.getMessage());
    }
}

세 가지 관련 사항 주장 가족 구성원을 완성하세요:

  • 어설트쓰로우 예외 유형 또는 해당 유형의 하위 유형을 허용합니다.
  • assertThrowsExactly 하위 클래스를 거부하므로 명명된 유형만 통과합니다.
  • assertDoesNotThrow 이는 블록이 깔끔하게 완료될 것이라는 정반대의 예상을 나타냅니다.

The JUnit 이 페이지의 코드 4개는 여전히 실행됩니다. JUnit 기존 엔진을 통해 플랫폼을 지원하므로 프로젝트 마이그레이션 중에도 계속 작동하도록 위의 코드를 다시 작성할 필요가 없습니다.

예외 테스트 시 흔히 저지르는 실수 JUnit

예외 테스트는 몇 가지 식별 가능한 방식으로 실패합니다. 각 행에는 증상, 원인 및 해결 방법이 명시되어 있습니다.

징후 원인 수정
예상되는 예외: java.lang.ArithmeticException 메서드가 예외 없이 완료되었습니다. 입력값이 실제로 유효하지 않은지 확인한 후 다시 실행하세요.
테스트는 통과했지만 잘못된 줄이 나갔습니다. expected 매개변수는 설정 과정을 포함하여 전체 메서드를 관찰합니다. 설정 위치를 옮기거나, 특정 호출 주변에 assertThrows를 사용하도록 변경하세요.
편집기에서 처리되지 않은 예외 유형 체크드 예외가 발생했지만 선언되지는 않았습니다. 테스트 메서드 시그니처에 예외 처리 조건을 추가하세요.
의도하지 않은 하위 클래스에서 테스트가 통과되었습니다. assertThrows는 명명된 형식의 하위 클래스를 허용합니다. 정확한 타입 일치를 위해서는 assertThrowsExactly를 사용하세요.
expected는 유효한 속성이 아닙니다. 이 테스트는 Jupiter의 @Test 어노테이션을 대상으로 컴파일되었습니다. org.junit.Test를 가져옵니다. JUnit 4, 또는 assertThrows로 이동합니다.

마지막 줄은 마이그레이션 도중에 가장 많은 사람들이 헷갈리는 부분인데, 두 어노테이션 모두 @Test라는 이름이 붙어 있고 임포트 구문에서만 구분할 수 있기 때문입니다.ping 한 JUnit 버전별 테스트 사례 해당 클래스는 문제의 전체 유형을 회피합니다.

자주 묻는 질문

예상되는 매개변수가 메시지를 확인할 수 없습니다. 해당 호출을 try 블록으로 감싸고, 바로 다음에 fail()을 호출한 다음, catch 블록 안에서 getMessage()에 대한 어설션을 실행하세요. JUnit 5번은 assertThrows가 포착된 예외를 반환하기 때문에 이를 더 간단하게 만듭니다.

JUnit 테스트가 실패하고 "예상되는 예외"라는 메시지와 함께 사용자가 지정한 클래스 이름이 표시됩니다. 그 외에는 아무것도 보고되지 않으므로, 예외를 전혀 발생시키지 않는 테스트는 실제 운영 환경에서 동작이 조용히 변경된 테스트와 동일하게 보입니다.

AI 어시스턴트는 메서드를 읽고 각 예외 발생문에 도달하는 입력값을 나열한 다음 분기별로 테스트 코드를 작성합니다. 이 출력 결과를 시작점으로 활용하세요. 어시스턴트는 코드에서 예외 유형을 추론하므로 잘못된 예외가 발생하더라도 테스트 코드에 그대로 복사됩니다.

부조종사 파일에 이미 존재하는 스타일을 따르므로, 혼합 프로젝트에서는 여러 스타일이 혼합되어 나타납니다. 제안을 수락하기 전에 가져오기(import) 줄을 확인하세요. org.junit.Test와 org.junit.jupiter.api.Test는 편집기에서 동일하게 보이기 때문입니다.

여전히 존재하지만, 더 이상 사용되지 않도록 권장되고 있습니다. JUnit 4.13 버전이며 Jupiter로 포팅되지 않았습니다. 기존 테스트 스위트는 그대로 사용할 수 있지만, 새로운 테스트는 가독성이 좋고 공개 규칙 필드가 필요 없는 assertThrows를 사용해야 합니다.

네. 람다 매개변수는 실행 가능한 객체이며, 예외를 발생시키도록 선언되어 있으므로 검사 예외를 처리하는 테스트 메서드 자체에는 throws 절이 필요하지 않습니다. 마찬가지로 다음 경우에도 적용됩니다. JUnit 4. 잡으려고 노력하다라는 관용구.

assertThrows는 지정한 형식의 모든 하위 클래스를 허용하므로 RuntimeException을 예상하는 경우 NullPointerException도 함께 전달됩니다. 정확한 클래스가 중요한 경우에는 assertThrowsExactly를 사용하거나 실제로 예상하는 가장 구체적인 형식을 지정하십시오.

예외가 조건의 일부인 경우에만tract. 메서드가 예외를 던질 것이라고 보장하지 않는 상황에서 의도치 않은 동작으로 락이 걸리게 되어 리팩토링이 어려워지고, 결국 테스트의 목적이 무의미해집니다.

이 게시물을 요약하면 다음과 같습니다.