Junit @ Before / @ After는 어떤 주문입니까?
통합 테스트 스위트가 있습니다. IntegrationTestBase
모든 시험을 연장 할 수있는 수업이 있습니다. 이 기본 클래스에는 API 및 DB 연결을 설정 하는 @Before
( public void setUp()
) 및 @After
( public void tearDown()
) 메소드가 있습니다. 내가 해왔 단지 각 테스트 케이스에서 그 두 가지 방법을 무시하고 호출 super.setUp()
하고 super.tearDown()
. 그러나 누군가가 수퍼에게 전화하는 것을 잊거나 잘못된 장소에두면 예외가 발생하고 마지막으로 또는 뭔가를 슈퍼라고 부르는 것을 잊어 버린 경우 문제가 발생할 수 있습니다.
내가하고 싶은 것은 만들 것입니다 setUp
및 tearDown
기본 클래스의 메소드를 final
다음 단지 우리 자신의 주석 추가 @Before
및 @After
방법을. 초기 테스트를 수행하면 항상 다음 순서로 호출되는 것으로 보입니다.
Base @Before
Test @Before
Test
Test @After
Base @After
하지만 주문이 보장되지 않아 문제가 발생할 수 있다고 우려합니다. 나는 둘러 보았고 주제에 대해 아무것도 보지 못했습니다. 내가 할 수 있고 문제가 없는지 아는 사람이 있습니까?
암호:
public class IntegrationTestBase {
@Before
public final void setUp() { *always called 1st?* }
@After
public final void tearDown() { *always called last?* }
}
public class MyTest extends IntegrationTestBase {
@Before
public final void before() { *always called 2nd?* }
@Test
public void test() { *always called 3rd?* }
@After
public final void after() { *always called 4th?* }
}
예,이 동작은 보장됩니다.
@Before
수퍼 클래스 의 메소드는 현재 클래스에서 대체되지 않는 한 현재 클래스 의 메소드보다 먼저 실행됩니다. 다른 순서는 정의되어 있지 않습니다.
@After
수퍼 클래스에 선언 된 메소드는 현재 클래스에서 재정의되지 않는 한 현재 클래스 의 메소드 이후에 실행됩니다.
전에 나를 물린 한 가지 잠재력이 있습니다.
@Before
클래스 @Before
내에서 정의 된 메소드 를 실행하는 순서 가 보장되지 않기 때문에 각 테스트 클래스마다 최대 하나의 메소드 를 갖고 싶습니다 . 일반적으로 이러한 메소드를 호출합니다 setUpTest()
.
그러나 @Before
로 문서화되어 있지만 The @Before methods of superclasses will be run before those of the current class. No other ordering is defined.
이것은 @Before
클래스 계층에서 고유 한 이름을 가진 각 메소드 가있는 경우에만 적용됩니다 .
예를 들어, 나는 다음을 가졌다 :
public class AbstractFooTest {
@Before
public void setUpTest() {
...
}
}
public void FooTest extends AbstractFooTest {
@Before
public void setUpTest() {
...
}
}
나는 AbstractFooTest.setUpTest()
전에 달릴 것으로 예상 FooTest.setUpTest()
했지만 FooTest.setupTest()
처형되었다. AbstractFooTest.setUpTest()
전혀 호출되지 않았습니다.
작동하려면 코드를 다음과 같이 수정해야합니다.
public void FooTest extends AbstractFooTest {
@Before
public void setUpTest() {
super.setUpTest();
...
}
}
나는의 문서를 기반으로 생각 @Before
하고 @After
올바른 결론은 방법에게 고유 한 이름을 제공하는 것입니다. 테스트에서 다음 패턴을 사용합니다.
public abstract class AbstractBaseTest {
@Before
public final void baseSetUp() { // or any other meaningful name
System.out.println("AbstractBaseTest.setUp");
}
@After
public final void baseTearDown() { // or any other meaningful name
System.out.println("AbstractBaseTest.tearDown");
}
}
과
public class Test extends AbstractBaseTest {
@Before
public void setUp() {
System.out.println("Test.setUp");
}
@After
public void tearDown() {
System.out.println("Test.tearDown");
}
@Test
public void test1() throws Exception {
System.out.println("test1");
}
@Test
public void test2() throws Exception {
System.out.println("test2");
}
}
결과적으로 주다
AbstractBaseTest.setUp
Test.setUp
test1
Test.tearDown
AbstractBaseTest.tearDown
AbstractBaseTest.setUp
Test.setUp
test2
Test.tearDown
AbstractBaseTest.tearDown
Advantage of this approach: Users of the AbstractBaseTest class cannot override the setUp/tearDown methods by accident. If they want to, they need to know the exact name and can do it.
(Minor) disadvantage of this approach: Users cannot see that there are things happening before or after their setUp/tearDown. They need to know that these things are provided by the abstract class. But I assume that's the reason why they use the abstract class
If you turn things around, you can declare your base class abstract, and have descendants declare setUp and tearDown methods (without annotations) that are called in the base class' annotated setUp and tearDown methods.
You can use @BeforeClass
annotation to assure that setup()
is always called first. Similarly, you can use @AfterClass
annotation to assure that tearDown()
is always called last.
This is usually not recommended, but it is supported.
It's not exactly what you want - but it'll essentially keep your DB connection open the entire time your tests are running, and then close it once and for all at the end.
This isn't an answer to the tagline question, but it is an answer to the problems mentioned in the body of the question. Instead of using @Before or @After, look into using @org.junit.Rule because it gives you more flexibility. ExternalResource (as of 4.7) is the rule you will be most interested in if you are managing connections. Also, If you want guaranteed execution order of your rules use a RuleChain (as of 4.10). I believe all of these were available when this question was asked. Code example below is copied from ExternalResource's javadocs.
public static class UsesExternalResource {
Server myServer= new Server();
@Rule
public ExternalResource resource= new ExternalResource() {
@Override
protected void before() throws Throwable {
myServer.connect();
};
@Override
protected void after() {
myServer.disconnect();
};
};
@Test
public void testFoo() {
new Client().run(myServer);
}
}
참고URL : https://stackoverflow.com/questions/6076599/what-order-are-the-junit-before-after-called
'Programing' 카테고리의 다른 글
'npm start'는 언제 사용하고 'ng serve'는 언제 사용합니까? (0) | 2020.07.05 |
---|---|
SQL Server 인덱스-오름차순 또는 내림차순으로 어떤 차이가 있습니까? (0) | 2020.07.05 |
`m_` 변수 접두사는 무엇을 의미합니까? (0) | 2020.07.05 |
"권한이있는 SSL / TLS 보안 채널에 대한 신뢰 관계를 설정할 수 없음"해결 방법 (0) | 2020.07.04 |
Vim에 파일을 저장하기 전에 변경 사항을 볼 수 있습니까? (0) | 2020.07.04 |