몇 가지 junit 테스트를 통해 리소스를 만들어야합니다.
이 논리를 구현하는 한 가지 방법은@Before
과@After
접근.
내가 한 일은 재사용 될 유틸리티 클래스의 생성을 캡슐화하는 것이 었습니다. 예 :
class UserCreatorTestUtil implements AutoClosable {
User create() {...}
void close() {...}
}
요점은 객체를 닫는 것을 기억할 필요없이 객체 자체가 닫히는 것입니다.@After
.
사용법은 다음과 같아야합니다.
@Test
void test() {
try (UserCreatorTestUtil userCreatorTestUtil = new UserCreatorTestUtil()) {
User user = userCreatorTestUtil.create();
// Do some stuff regarding the user's phone
Assert.assertEquals("123456789", user.getPhone());
}
}
문제는 junit의 assert 키워드가Error
- 아니야.Exception
.
자원을 사용하여 시험 사용이 "catch"할 것인가?Error
close 메소드를 호출할까요?
*에서 답변을 찾을 수 없습니다.자원을 사용하여 시험 사용 설명서.
그것은하지 않는다.catch
아무것도. 하지만finally
모든 자원을 닫으십시오.
finally
블록들오류가 발생해도 실행됩니다..
finally
블록 할 것입니다. - ThiloSystem.exit()
:stackoverflow.com/questions/14905006/… - Christophe Roussyfinally
블록과는 달리,finally
차단하면 모든 후속 작업을Throwable
의close()
작업을 추가하고억제 된기본 throwable에 던져 넣을 수 있습니다. 에이finally
블록은 기본 throwable에 대한 지식이 없으므로이를 수행 할 수 없습니다. - Holgerfinally
블록게다가~에catch
블록은 실제로 아무것도 잡을 수 없습니다 (단지 기본 throwable과 rethrows를 기록합니다). 모든 "동작" finally 블록에서 발생합니다. 자세한 내용은 @Nicolas answer를 참조하십시오. - Thilo
기본의 의사 코드자원을 사용하여 시험 사용성명서는 (cfJava Language Specification §14.20.3.1
) :
final VariableModifiers_minus_final R Identifier = Expression;
Throwable #primaryExc = null;
try ResourceSpecification_tail
Block
catch (Throwable #t) {
#primaryExc = #t;
throw #t;
} finally {
if (Identifier != null) {
if (#primaryExc != null) {
try {
Identifier.close();
} catch (Throwable #suppressedExc) {
#primaryExc.addSuppressed(#suppressedExc);
}
} else {
Identifier.close();
}
}
}
보시다시피 잡기Throwable
아니Exception
포함하는Error
그러나오직 기본 예외를 얻기 위해서억제 된 예외로 자원을 닫는 동안 발생한 예외를 추가합니다.
또한 리소스가finally
블록그들은 무슨 일이 있어도 닫힐 것이다.(단,System.exit
물론 현재 실행중인 Java Virtual Machine을 종료 할 때)Error
또는Throwable
던졌습니다.
javac
이 복잡한 형식 표준을 그대로 따른다. 그걸 고려해서finally
결국 두 경우에 코드 중복을 통해 구현됩니다. 변수에 예외를 저장하고이를 테스트하는 것은 전혀 의미가 없습니다.null
, 예외가 있는지 여부에 상관없이 이미 코드 경로에 의해 암시 된 경우 ... - Holgerfinally
예외가 있었는지의 여부와 관계없이 블록이 실행됩니다. 무슨 코드 중복을 의미합니까?Identifier.close()
) 그리고 왜 당신을 괴롭 히 느냐? 리소스를 사용하여 재시도해야한다고 제안 하시겠습니까? - siegifinally
따라서, afinally
블록은 블록을 떠날 수있는 모든 코드 경로에 액션을 복사하여 컴파일되며 예외 처리기, 즉try { foo(); } finally { bar(); }
~에 컴파일된다try { foo(); } catch(Throwable t) { bar(); throw t; } bar();
,bar()
호출 코드. 예외가 발생했는지 여부에 상관없이 코드 경로에 의해 암시됩니다. 즉 첫 번째bar();
호출은 예외적 인 조건하에있는 호출이며, 두 번째 호출은 예외 조건입니다. - Holgerjavac
이것의 결과로이 질문. 저의 대답에서 저는이 행동을 "어떻게javac
내부적으로 ", 명명하지 않고"finally
블록 (block) "이라고 말하면서,이 시점에서 정식 명세를 알지 못했기 때문에 간단히 말하면, 모든 것이 명확해진다. - Holgerjavac
그러나 간단히 "desugar" 그것을 언어 명세에 따라 작성한 다음 JIT 컴파일러가 그 일을하도록하십시오. - siegi
자원을 사용해보십시오 (Try-with-resources)는 그 자체로 어떤 것도 잡아 내지 못합니다.
그러나catch
try-with-resources 블록의 끝까지 차단하고Throwable
너는 좋아한다:
try (UserCreatorTestUtil userCreatorTestUtil = new UserCreatorTestUtil()) {
// ... Whatever
} catch (RuntimeException e) {
// Handle e.
} catch (Exception | Throwable t) {
// Handle t.
}
뒤에있는 생각try-with-resources
리소스를 닫아야하는지 확인하는 것입니다.
기존의 문제try-catch-finally
진술은 당신의try
블록은 예외를 throw합니다. 이제는 보통 그 예외를finally
블록.
이제 finally 블록에서도 예외가 발생한다고 가정합니다. 이 경우 try catch에 의해 throw 된 예외는잃어버린및에서 생성 된 예외finally
블록이 전파됩니다.
try {
// use something that's using resource
// e.g., streams
} catch(IOException e) {
// handle
} finally {
stream.close();
//if any exception occurs in the above line, than that exception
//will be propagated and the original exception that occurred
//in try block is lost.
}
에서try-with-resources
그만큼close()
리소스의 메소드가 자동으로 호출되며,close()
예외를 던집니다.finally
에 도달하지 못하고 원래의 예외가 손실됩니다.
이것과 대조 :
try (InputStream inputStream= new FileInputStream("C://test.txt")){
// ... use stream
} catch(IOException e) {
// handle exception
}
위의 코드 스 니펫에서close()
메서드가 자동으로 호출되면close()
메서드는 또한 모든 예외를 생성합니다. 예외는 자동으로 표시되지 않습니다.
마지막에 대한 오해 : try-with-resources 않습니다.아니~을해라.잡기.
그것은 않습니다결정적인 마침내따라서 "문제"의 종류는 중요하지 않습니다.
자세한 내용은JLS자세한 내용은!