programing

예외가 발생하지 않았는지 테스트하려면 어떻게 해야 합니까?

newsource 2022. 12. 26. 20:28

예외가 발생하지 않았는지 테스트하려면 어떻게 해야 합니까?

한 가지 방법은 다음과 같습니다.

@Test
public void foo() {
   try {
      // execute code that you expect not to throw Exceptions.
   } catch(Exception e) {
      fail("Should not have thrown any exception");
   }
}

더 (s' jun jun jun jun jun ( ( (?) ( Junit )@Rule

잘못 접근하고 있어요.기능 테스트만 하면 됩니다.예외가 발생하면 테스트는 자동으로 실패합니다.예외가 발생하지 않으면 모든 테스트가 녹색으로 표시됩니다.

이 질문은 가끔 흥미를 끌기 때문에 조금 더 자세히 설명하겠습니다.

유닛 테스트의 배경

유닛 테스트에서는 작업단위를 정의하는 것이 중요합니다.기본적으로 단일 기능을 나타내는 여러 메서드 또는 클래스를 포함할 수도 있고 포함하지 않을 수도 있는 코드베이스 추출입니다.

또는 유닛 테스트의 기술, Roy Oshrove의 제2판, 11페이지에 정의된 바와 같이:

유닛 테스트는 테스트 대상 작업 단위를 호출하고 해당 유닛의 단일 최종 결과에 대한 몇 가지 가정을 확인하는 자동화된 코드입니다.단위 테스트는 거의 항상 단위 테스트 프레임워크를 사용하여 작성됩니다.쉽게 쓸 수 있고 빠르게 실행할 수 있습니다.신뢰할 수 있고, 읽기 쉬우며, 유지보수가 가능합니다.생산 코드가 변경되지 않는 한 결과는 일관성이 있습니다.

깨달아야 할 중요한 것은 한 작업단위는 보통 하나의 방법이 아니라 매우 기본적인 수준에서는 하나의 방법이며 그 후에는 다른 작업단위에 의해 캡슐화된다는 것입니다.

여기에 이미지 설명 입력

이상적으로는 각 개별 작업 단위에 대한 테스트 방법을 가지고 있어야 합니다. 그래야 문제가 발생한 부분을 항상 즉시 볼 수 있습니다.인 이예 called called, 고 called called called called called called called called called called called called called called called called called called called called called called called called called called called 라는 방법이 있습니다.getUserById()3번입니다.

첫 번째 작업 단위는 유효한 입력과 비활성 입력의 경우 유효한 사용자가 반환되는지 여부를 테스트해야 합니다.
데이터 소스에 의해 발생하는 예외는 여기서 처리해야 합니다.사용자가 존재하지 않는 경우 사용자를 찾을 수 없을 때 예외가 발생함을 증명하는 테스트가 있어야 합니다.를 들어, 「 」, 「 」를 들 수 있습니다.IllegalArgumentException the the the the the 로 잡혔어요.@Test(expected = IllegalArgumentException.class)석입니니다다

이 기본 작업 단위에 대한 모든 사용 사례를 처리한 후에는 한 단계 더 올라갑니다.이 예에서는 동일한 작업을 수행하지만 현재 수준 바로 아래의 예외만 처리합니다.이렇게 하면 테스트 코드가 잘 구조화되어 있기 때문에 여기저기 뛰어다닐 필요 없이 아키텍처에서 빠르게 문제를 찾을 수 있습니다.

테스트의 유효 및 오류 입력 처리

이 시점에서 이러한 예외를 어떻게 처리할지는 명확해야 합니다.입력에는 유효한 입력과 잘못된 입력의 두 가지 유형이 있습니다(엄격한 의미에서 입력은 유효하지만 올바르지 않습니다).

유효한 입력으로 작업하면 어떤 테스트를 작성해도 작동한다는 암묵적인 기대치를 설정할 수 있습니다.

existingUserById_ShouldReturn_UserObject이 방법이 실패하면(예외가 느려지는 등), 뭔가 잘못되었다는 것을 알고 파헤치기 시작할 수 있습니다.

으로써(</FONT CHANGE:></(</FONT CHANGE:>)nonExistingUserById_ShouldThrow_IllegalArgumentException는, 에러가 있는 입력을 사용하고, 예외가 예상되는 경우, 사용의 메서드가 잘못된 입력에 대해 정상적으로 동작하고 있는지 아닌지를 확인할 수 있습니다.

TL;DR

테스트에서 두 가지 작업을 수행하려고 했습니다. 입력이 유효하고 오류가 있는지 확인합니다.이것을 각각 1개의 작업을 실행하는 2개의 방법으로 분할하면, 보다 명확한 테스트와 문제가 발생하는 부분의 개요를 얻을 수 있습니다.

계층화된 작업 단위를 염두에 두면 하위 계층에서 잘못되었을 수 있는 모든 사항을 고려할 필요가 없기 때문에 계층에서 상위 계층에 필요한 테스트 양을 줄일 수 있습니다. 즉, 현재 계층 아래의 계층은 종속성이 작동하며 문제가 발생할 경우 가상 보증입니다.현재 레이어에 있습니다(하위 레이어는 에러를 발생시키지 않습니다).

소나 큐브의 "오징어:S2699": "이 테스트 케이스에 적어도 하나의 어설션을 추가합니다."

나는 예외 없이 합격하는 것이 유일한 목표인 간단한 시험을 치렀다.

다음 간단한 코드를 고려합니다.

public class Printer {

    public static void printLine(final String line) {
        System.out.println(line);
    }
}

이 방법을 테스트하기 위해 어떤 종류의 주장을 추가할 수 있습니까?물론 시험삼아 잡아볼 수는 있지만, 그건 코드 블롯일 뿐입니다.

솔루션은 JUnit 자체에서 나옵니다.

이 , '예외'를 추가합니다.expected다음 예시와 같습니다.

@Test(expected = Test.None.class /* no exception expected */)
public void test_printLine() {
    Printer.printLine("line");
}

Test.None.class는 예상되는 값의 기본값입니다.

당신이 가 if if if ifimport org.junit.Test.None 쓰면 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아

@Test(expected = None.class)

더 읽기 쉽다고 생각하실 수도 있습니다.

JUnit 5(Jupiter)는 예외 부재/존재를 체크하는 3가지 기능을 제공합니다.

assertAll​()

모두 제공되었다고 단언합니다.executables
예외를 두지 마세요.

assertDoesNotThrow​()

의 실행을 단언합니다.
executable/supplier
어떠한 예외도 던지지 않습니다.

은 사용할 수 .
JUnit 5.2.0(2018년 4월 29일) 이후.

assertThrows​()

제공된 명령어의 실행을 주장합니다.executable
예외로 합니다.expectedType
예외를 반환합니다.

package test.mycompany.myapp.mymodule;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class MyClassTest {

    @Test
    void when_string_has_been_constructed_then_myFunction_does_not_throw() {
        String myString = "this string has been constructed";
        assertAll(() -> MyClass.myFunction(myString));
    }
    
    @Test
    void when_string_has_been_constructed_then_myFunction_does_not_throw__junit_v520() {
        String myString = "this string has been constructed";
        assertDoesNotThrow(() -> MyClass.myFunction(myString));
    }

    @Test
    void when_string_is_null_then_myFunction_throws_IllegalArgumentException() {
        String myString = null;
        assertThrows(
            IllegalArgumentException.class,
            () -> MyClass.myFunction(myString));
    }

}

JUnit 5 이전 버전의 경우:

AssertJ fluent assertions 3.7.0의 경우:

Assertions.assertThatCode(() -> toTest.method())
    .doesNotThrowAnyException();

업데이트:

는 JUnit 5를 도입했습니다.assertDoesNotThrow()당신의 프로젝트에 종속성을 추가하는 대신 그것을 사용하고 싶습니다.상세한 것에 대하여는, 다음의 회답을 참조해 주세요.

Java 8은 이를 훨씬 쉽게 만들지만 Kotlin/Scala는 두 배로 더 쉽게 만들 수 있습니다.

우리는 약간의 효용 수업을 쓸 수 있다.

class MyAssertions{
  public static void assertDoesNotThrow(FailingRunnable action){
    try{
      action.run()
    }
    catch(Exception ex){
      throw new Error("expected action not to throw, but it did!", ex)
    }
  }
}

@FunctionalInterface interface FailingRunnable { void run() throws Exception }

그러면 코드는 단순해집니다.

@Test
public void foo(){
  MyAssertions.assertDoesNotThrow(() -> {
    //execute code that you expect not to throw Exceptions.
  }
}

Java-8에 접속할 수 없는 경우, 저는 매우 오래된 자바 기능을 사용하고 싶습니다: aribitrary code blocks와 간단한 comment.

//setup
Component component = new Component();

//act
configure(component);

//assert 
/*assert does not throw*/{
  component.doSomething();
}

마지막으로, 최근 제가 좋아하는 언어인 코틀린을 소개합니다.

fun (() -> Any?).shouldNotThrow() 
    = try { invoke() } catch (ex : Exception){ throw Error("expected not to throw!", ex) }

@Test fun `when foo happens should not throw`(){

  //...

  { /*code that shouldn't throw*/ }.shouldNotThrow()
}

당신이 정확히 어떻게 표현하고 싶은지 만지작거릴 여지가 많지만, 저는 항상 유창한 주장의 팬이었습니다.


에 관하여

잘못 접근하고 있어요.기능 테스트만 하면 됩니다.예외가 발생하면 테스트는 자동으로 실패합니다.예외가 발생하지 않으면 모든 테스트가 녹색으로 표시됩니다.

이것은 원칙적으로는 맞지만 결론은 틀렸다.

자바어에 의해 (API API) JRE 실행 시)와 같은 .Double.parseDouble a를 NumberFormatException ★★★★★★★★★★★★★★★★★」Paths.get a를 InvalidPathException

Number를 하는 컴포넌트는 Number String for Number 입니다.Double.ParseDoubleRegex, 손으로 쓴 파서, 또는 더블의 범위를 특정 범위로 제한하는 다른 도메인 규칙을 포함하는 것을 사용할 수 있습니다.이 컴포넌트를 테스트하는 최선의 방법은 무엇입니까?필자는 결과 문자열을 구문 분석할 때 예외가 발생하지 않는다고 주장하는 것이 명백한 테스트라고 생각합니다.는 위의 중 해서 그 하겠습니다.assertDoesNotThrow ★★★★★★★★★★★★★★★★★」/*comment*/{code} 막다, , 막다, 막다, 막다. 하다, 하다

@Test public void given_validator_accepts_string_result_should_be_interpretable_by_doubleParseDouble(){
  //setup
  String input = "12.34E+26" //a string double with domain significance

  //act
  boolean isValid = component.validate(input)

  //assert -- using the library 'assertJ', my personal favourite 
  assertThat(isValid).describedAs(input + " was considered valid by component").isTrue();
  assertDoesNotThrow(() -> Double.parseDouble(input));
}

해 합니다.input또는 를 사용하여 이 테스트를 다른 입력에 더 쉽게 재사용할 수 있습니다.또, 이국적인 것을 원한다면, 테스트 생성 툴(그리고 이것)을 선택할 수도 있습니다.TestNG는 파라미터화된 테스트를 더 잘 지원합니다.

에 들지 않는 은, 「어느 쪽이 좋다」, 「어느 쪽이 좋다」의 사용법입니다.@Test(expectedException=IllegalArgumentException.class)이 예외는 위험할 정도로 광범위합니다.테스트 대상 컴포넌트의 컨스트럭터가 다음을 수행하도록 코드가 변경된 경우if(constructorArgument <= 0) throw IllegalArgumentException()테스트 데이터를 올바르게 생성하는 것은 매우 어려운 문제이기 때문에 편리하기 때문에 테스트에서는 그 인수에 대해0 을 지정하고 있습니다.그것은 매우 일반적인 일이며, 테스트 데이터를 올바르게 생성하는 것은 의외로 어려운 문제이기 때문에 테스트에서는 아무것도 테스트하지 않아도 녹색 막대가 됩니다.런름름 름 름 름 、 름 름 름 、 름 름 름 、

코드의 오류를 모두 검출할 수 있을 정도로 운이 나쁜 경우.바보같이 해도 돼

class DumpTest {
    Exception ex;
    @Test
    public void testWhatEver() {
        try {
            thisShouldThrowError();
        } catch (Exception e) {
            ex = e;
        }
        assertEquals(null,ex);
    }
}

이 게시물이 6년이 되었지만, 주니트 세계에서는 많은 것이 바뀌었다.Junit5를 사용하면

org.junit.jupiter.api.Assertions.assertDoesNotThrow()

예:

public void thisMethodDoesNotThrowException(){
   System.out.println("Hello There");
}

@Test
public void test_thisMethodDoesNotThrowException(){
  org.junit.jupiter.api.Assertions.assertDoesNotThrow(
      ()-> thisMethodDoesNotThrowException()
    );
}

Junit5의 새로운 버전을 사용하는 사용자에게 도움이 되기를 바랍니다.

JUnit5는 이 목적을 위해 assertAll() 메서드를 추가합니다.

assertAll( () -> foo() )

출처: JUnit 5 API

다음과 같은 무효 방법을 사용하여 시나리오를 테스트하는 방법

void testMeWell() throws SomeException {..}

예외를 발생시키지 않으려면:

Junit5

assertDoesNotThrow(() -> {
    testMeWell();
});

테스트 대상이 예외를 소비하는지 여부를 테스트하는 경우.테스트를 (jMock2를 사용하는 Mock 공동작업자)로 둡니다.

@Test
public void consumesAndLogsExceptions() throws Exception {

    context.checking(new Expectations() {
        {
            oneOf(collaborator).doSth();
            will(throwException(new NullPointerException()));
        }
    });

    target.doSth();
 }

대상이 던져진 예외를 소비하면 테스트가 통과되고 그렇지 않으면 테스트가 실패합니다.

예외 소비 논리를 테스트하려면 상황이 더 복잡해집니다.나는 조롱당할 수 있는 소비를 협력자에게 위임할 것을 제안한다.따라서 테스트는 다음과 같습니다.

@Test
public void consumesAndLogsExceptions() throws Exception {
    Exception e = new NullPointerException();
    context.checking(new Expectations() {
        {
            allowing(collaborator).doSth();
            will(throwException(e));

            oneOf(consumer).consume(e);
        }
    });

    target.doSth();
 }

그러나 로그만 기록하려고 하면 지나치게 설계될 수 있습니다.이 경우 tdd를 고집하시면 이 기사(http://java.dzone.com/articles/monitoring-declarative-transac, http://blog.novoj.net/2008/09/20/testing-aspect-pointcuts-is-there-an-easy-way/) 를 참조해 주십시오.

assert Null 사용(...)

@Test
public void foo() {
    try {
        //execute code that you expect not to throw Exceptions.
    } catch (Exception e){
        assertNull(e);
    }
}

이것이 최선의 방법은 아닐 수도 있지만 테스트 중인 코드 블록에서 예외가 발생하지 않도록 합니다.

import org.assertj.core.api.Assertions;
import org.junit.Test;

public class AssertionExample {

    @Test
    public void testNoException(){
        assertNoException();
    }    

    private void assertException(){
        Assertions.assertThatThrownBy(this::doNotThrowException).isInstanceOf(Exception.class);
    }

    private void assertNoException(){
        Assertions.assertThatThrownBy(() -> assertException()).isInstanceOf(AssertionError.class);
    }

    private void doNotThrowException(){
        //This method will never throw exception
    }
}

저도 같은 상황에 직면했습니다. 저는 예외가 발생해야 할 때, 그리고 발생해야 할 때만 발생하는지 확인해야 했습니다.예외 핸들러를 사용하여 다음 코드를 사용할 수 있게 되었습니다.

    try {
        functionThatMightThrowException()
    }catch (Exception e){
        Assert.fail("should not throw exception");
    }
    RestOfAssertions();

나에게 가장 큰 장점은 이 구조가 매우 간단하다는 것과 "if and only if"의 다른 방법을 확인할 수 있다는 것이다.

규칙을 생성하면 예외가 발생하지 않을 수 있습니다.

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

이를 수행하려면 @Rule을 사용하여 메서드 reportMissingException을 호출합니다.With Message는 다음과 같습니다.스칼라 코드입니다

여기에 이미지 설명 입력

다음과 같은 일반적인 방법을 개발했기 때문에 이 문제에 부딪혔습니다.

@Test
void testSomething() {
   checkGeneric(anComplexObect)
}

https://newbedev.com/sonarqube-issue-add-at-least-one-assertion-to-this-test-case-for-unit-test-with-assertions에서는 주석 관련 내용을 제안하고 있습니다.

해결책은 훨씬 더 간단합니다."checkGeneric" 메서드의 이름을 "assertGeneric"으로 바꾸면 됩니다.

@Test
void testSomething() {
  assertGeneric(anComplexObect)
}

junit의 어사션을 기반으로 임의의 종류의 어사션을 작성할 수 있습니다.이러한 어사션은 junit과 동일하게 동작하는 사용자 정의 어사션을 작성하기 위해 특별히 설계되어 있기 때문입니다.

static void assertDoesNotThrow(Executable executable) {
    assertDoesNotThrow(executable, "must not throw");
}
static void assertDoesNotThrow(Executable executable, String message) {
    try {
        executable.execute();
    } catch (Throwable err) {
        fail(message);
    }
}

이제 이른바 시나리오 method Must Not Throw를 테스트하고 모든 장애를 junit 스타일로 기록합니다.

//test and log with default and custom messages
//the following will succeed
assertDoesNotThrow(()->methodMustNotThrow(1));
assertDoesNotThrow(()->methodMustNotThrow(1), "custom facepalm");
//the following will fail
assertDoesNotThrow(()->methodMustNotThrow(2));
assertDoesNotThrow(()-> {throw new Exception("Hello world");}, "message");
//See implementation of methodMustNotThrow below

으로 어떤에서 불합격할 에서든, 「어느 경우든, 「어느 경우든」에 을 하면 불합격할 이 있습니다.콜을 통해 납득할 수 있는 장소에서는 테스트에 불합격할 가능성이 있습니다.fail(someMessage)이 목적을 위해 정확히 설계되어 있습니다.예를 들어 테스트 케이스에 어떤 것이 던져진 경우 실패하기 위해 테스트/캐치 블록에서 사용합니다.

try{methodMustNotThrow(1);}catch(Throwable e){fail("must not throw");}
try{methodMustNotThrow(1);}catch(Throwable e){Assertions.fail("must not throw");}

특정 상황에서 실패해서는 안 되지만 실패할 수 있는 방법이 있다고 가정할 때 테스트하는 방법의 예를 다음에 나타냅니다.

void methodMustNotThrow(int x) throws Exception {
    if (x == 1) return;
    throw new Exception();
}

위의 방법은 간단한 샘플입니다.그러나 이는 장애가 명백하지 않은 복잡한 상황에서는 효과가 있습니다.Import는 다음과 같습니다.

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static org.junit.jupiter.api.Assertions.*;

다음은 모든 예외 테스트에 불합격합니다(체크박스를 켜거나 끄거나).

@Test
public void testMyCode() {

    try {
        runMyTestCode();
    } catch (Throwable t) {
        throw new Error("fail!");
    }
}

언급URL : https://stackoverflow.com/questions/17731234/how-to-test-that-no-exception-is-thrown