programing

JUnit 테스트 주석을 사용하여 예외 메시지를 강조하려면 어떻게 해야 합니까?

yoursource 2022. 12. 11. 10:39
반응형

JUnit 테스트 주석을 사용하여 예외 메시지를 강조하려면 어떻게 해야 합니까?

JUnit과 함께 를 몇 개 했습니다.@Test 방법이 하려면 JUnit을 사용하여 그렇게 있습니까?@Test석? 은 이 됩니까?AFAIK, JUnit 4.7은 이 기능을 제공하지 않지만 향후 버전에서는 이 기능을 제공합니까?고고있있있있다다NET net net net net net net net net net net 。Java ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」

내가 원하는 건 이거야

@Test (expected = RuntimeException.class, message = "Employee ID is null")
public void shouldThrowRuntimeExceptionWhenEmployeeIDisNull() {}

다음과 같이 주석을 사용할 수 있습니다.

@Rule
public ExpectedException expectedEx = ExpectedException.none();

@Test
public void shouldThrowRuntimeExceptionWhenEmployeeIDisNull() throws Exception {
    expectedEx.expect(RuntimeException.class);
    expectedEx.expectMessage("Employee ID is null");

    // do something that should throw the exception...
    System.out.println("=======Starting Exception process=======");
    throw new NullPointerException("Employee ID is null");
}

기재되어 있는 해 주십시오.ExpectedException.- constructor가에 docs를 .공용 컨스트럭터가 없기 때문에 사용해야 합니다.ExpectedException.none().

JUnit 4.13에서는 다음 작업을 수행할 수 있습니다.

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;

...

@Test
void exceptionTesting() {
  IllegalArgumentException exception = assertThrows(
    IllegalArgumentException.class, 
    () -> { throw new IllegalArgumentException("a message"); }
  );

  assertEquals("a message", exception.getMessage());
}

이것은 JUnit 5에서도 동작하지만 Import가 다릅니다.

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

...

난 그 답이 좋아.하지만 어떤 이유로든 규칙을 사용하고 싶지 않다면.세 번째 옵션이 있습니다.

@Test (expected = RuntimeException.class)
public void myTestMethod()
{
   try
   {
      //Run exception throwing operation here
   }
   catch(RuntimeException re)
   {
      String message = "Employee ID is null";
      assertEquals(message, re.getMessage());
      throw re;
    }
    fail("Employee Id Null exception did not throw!");
  }

ㅇㅇㅇㅇㅇㅇㅇ를 써야 하나요?@Test(expected=SomeException.class)예외의 실제 메시지를 주장할 필요가 있는 경우, 이것이 우리가 하는 일입니다.

@Test
public void myTestMethod()
{
  try
  {
    final Integer employeeId = null;
    new Employee(employeeId);
    fail("Should have thrown SomeException but did not!");
  }
  catch( final SomeException e )
  {
    final String msg = "Employee ID is null";
    assertEquals(msg, e.getMessage());
  }
}

사실, 가장 좋은 방법은 시도/잡기입니다. 왜일까요?예외를 예상하는 장소를 제어할 수 있기 때문입니다.

다음 예를 생각해 보겠습니다.

@Test (expected = RuntimeException.class)
public void someTest() {
   // test preparation
   // actual test
}

어느 날 코드가 수정되어 테스트 준비로 인해 Runtime이 느려지면 어떻게 됩니까?예외?이 경우 실제 테스트는 테스트조차 되지 않으며 예외가 발생하지 않더라도 테스트는 합격합니다.

그렇기 때문에 주석에 의존하는 것보다 try/catch를 사용하는 것이 훨씬 좋습니다.

레이스톰은 좋은 대답을 했다.나도 룰을 별로 좋아하지 않아.비슷한 작업을 하고 있습니다만, 가독성과 조작성을 높이기 위해 다음과 같은 유틸리티 클래스를 만듭니다.이것은 주석의 큰 장점 중 하나입니다.

다음 유틸리티 클래스 추가:

import org.junit.Assert;

public abstract class ExpectedRuntimeExceptionAsserter {

    private String expectedExceptionMessage;

    public ExpectedRuntimeExceptionAsserter(String expectedExceptionMessage) {
        this.expectedExceptionMessage = expectedExceptionMessage;
    }

    public final void run(){
        try{
            expectException();
            Assert.fail(String.format("Expected a RuntimeException '%s'", expectedExceptionMessage));
        } catch (RuntimeException e){
            Assert.assertEquals("RuntimeException caught, but unexpected message", expectedExceptionMessage, e.getMessage());
        }
    }

    protected abstract void expectException();

}

유닛 테스트에서는 다음 코드만 있으면 됩니다.

@Test
public void verifyAnonymousUserCantAccessPrivilegedResourceTest(){
    new ExpectedRuntimeExceptionAsserter("anonymous user can't access privileged resource"){
        @Override
        protected void expectException() {
            throw new RuntimeException("anonymous user can't access privileged resource");
        }
    }.run(); //passes test; expected exception is caught, and this @Test returns normally as "Passed"
}

나는 주니트와 예외를 주장하는 방식이 마음에 들지 않았다.주석에서 "예상"을 사용하면 테스트 정의의 맨 위에 "그때"가 배치되기 때문에 "주어진, 언제, 그때" 패턴을 위반하는 것으로 보입니다.

또, 「@Rule」을 사용하면, 보일러 플레이트 코드가 너무 많아집니다.테스트용으로 새로운 라이브러리를 설치할 수 있다면 AssertJ(이 라이브러리는 현재 SpringBoot에 포함되어 있습니다)를 참조해 주십시오.

그런 다음 "given/when/then" 원칙을 위반하지 않는 테스트를 수행하고 AssertJ를 사용하여 다음을 확인합니다.

1 - 예외는 예상대로입니다.2 - 예상된 메시지도 있습니다.

다음과 같이 됩니다.

 @Test
void should_throwIllegalUse_when_idNotGiven() {

    //when
    final Throwable raisedException = catchThrowable(() -> getUserDAO.byId(null));

    //then
    assertThat(raisedException).isInstanceOf(IllegalArgumentException.class)
            .hasMessageContaining("Id to fetch is mandatory");
}

@Rule을 사용하는 경우 예외 세트는 Test 클래스의 모든 테스트 메서드에 적용됩니다.

user64141의 답변은 마음에 들지만 좀 더 일반화될 수 있다는 것을 알았습니다.제 생각은 이렇습니다.

public abstract class ExpectedThrowableAsserter implements Runnable {

    private final Class<? extends Throwable> throwableClass;
    private final String expectedExceptionMessage;

    protected ExpectedThrowableAsserter(Class<? extends Throwable> throwableClass, String expectedExceptionMessage) {
        this.throwableClass = throwableClass;
        this.expectedExceptionMessage = expectedExceptionMessage;
    }

    public final void run() {
        try {
            expectException();
        } catch (Throwable e) {
            assertTrue(String.format("Caught unexpected %s", e.getClass().getSimpleName()), throwableClass.isInstance(e));
            assertEquals(String.format("%s caught, but unexpected message", throwableClass.getSimpleName()), expectedExceptionMessage, e.getMessage());
            return;
        }
        fail(String.format("Expected %s, but no exception was thrown.", throwableClass.getSimpleName()));
    }

    protected abstract void expectException();

}

"fail" 문을 try block 내에 두면 관련 어설션 예외가 검출됩니다.catch 문 내에서 return을 사용하면 이를 방지할 수 있습니다.

저는 AssertJ를 선호합니다.

        assertThatExceptionOfType(ExpectedException.class)
        .isThrownBy(() -> {
            // method call
        }).withMessage("My message");

catch-exception 라이브러리를 Import하여 사용합니다.더 깔끔하고ExpectedException규칙 또는 atry-catch.

문서의 예를 다음에 나타냅니다.

import static com.googlecode.catchexception.CatchException.*;
import static com.googlecode.catchexception.apis.CatchExceptionHamcrestMatchers.*;

// given: an empty list
List myList = new ArrayList();

// when: we try to get the first element of the list
catchException(myList).get(1);

// then: we expect an IndexOutOfBoundsException with message "Index: 1, Size: 0"
assertThat(caughtException(),
  allOf(
    instanceOf(IndexOutOfBoundsException.class),
    hasMessage("Index: 1, Size: 0"),
    hasNoCause()
  )
);
@Test (expectedExceptions = ValidationException.class, expectedExceptionsMessageRegExp = "This is not allowed")
public void testInvalidValidation() throws Exception{
     //test code
}

언급URL : https://stackoverflow.com/questions/2469911/how-do-i-assert-my-exception-message-with-junit-test-annotation

반응형