Development Tip

수업 전 Junit (비 정적)

yourdevel 2020. 10. 19. 12:55
반응형

수업 전 Junit (비 정적)


Junit이 테스트 파일에서 한 번 함수를 실행하도록하는 모범 사례가 있습니까? 또한 정적이어서는 안됩니다.

@BeforeClass비 정적 기능 처럼 ?

추악한 해결책은 다음과 같습니다.

@Before void init(){
    if (init.get() == false){
        init.set(true);
        // do once block
    }
}

글쎄 이것은 내가하고 싶지 않은 일이며 통합 된 junit 솔루션을 찾고 있습니다.


일회성 초기화를 위해 정적 이니셜 라이저를 설정하고 싶지 않고 JUnit 사용에 대해 특별히 신경 쓰지 않는 경우 TestNG를 살펴보십시오. TestNG는 모두 주석을 사용하여 다양한 구성 옵션으로 비 정적 일회성 초기화를 지원합니다.

TestNG에서 이것은 다음과 같습니다.

@org.testng.annotations.BeforeClass
public void setUpOnce() {
   // One time initialization.
}

분해를 위해

@org.testng.annotations.AfterClass
public void tearDownOnce() {
   // One time tear down.
}

JUnit 4 @Before및에 해당하는 TestNG의 @After경우 @BeforeMethod@AfterMethod각각을 사용할 수 있습니다 .


간단한 if 문도 잘 작동하는 것 같습니다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class myTest {

    public static boolean dbInit = false;

    @Autowired
    DbUtils dbUtils;

    @Before
    public void setUp(){

        if(!dbInit){

            dbUtils.dropTables();
            dbUtils.createTables();
            dbInit = true;

        }
    }

 ...

빈 생성자를 사용하는 것이 가장 쉬운 해결책입니다. 확장 클래스에서 생성자를 계속 재정의 할 수 있습니다.

그러나 그것은 모든 상속에 최적이 아닙니다. 이것이 JUnit 4가 대신 주석을 사용하는 이유입니다.

또 다른 옵션은 factory / util 클래스에서 도우미 메서드를 만들고 해당 메서드가 작업을 수행하도록하는 것입니다.

Spring을 사용하는 경우 @TestExecutionListeners주석 사용을 고려해야합니다 . 이 테스트와 같은 것 :

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({CustomTestExecutionListener.class, 
     DependencyInjectionTestExecutionListener.class})
@ContextConfiguration("test-config.xml")
public class DemoTest {

AbstractTestExecutionListener예를 들어 Spring 에는 재정의 할 수있는이 빈 메서드가 포함되어 있습니다.

public void beforeTestClass(TestContext testContext) throws Exception {
    /* no-op */
}

참고 : NOT 간과 / 미스 DO DependencyInjectionTestExecutionListener사용자를 추가하는 동안 TestExecutionListeners. 그렇게하면 모든 autowire가 null.


@BeforeAllMethods/ @AfterAllMethods주석을 쉽게 사용 하여 삽입 된 모든 값을 사용할 수있는 인스턴스 컨텍스트 (비 정적) 내에서 메서드를 실행합니다.

There is a special testing library for this:

https://mvnrepository.com/artifact/org.bitbucket.radistao.test/before-after-spring-test-runner/0.1.0

https://bitbucket.org/radistao/before-after-spring-test-runner/

The only limitation: works only for Spring testing.

(I'm the developer of this testing library)


I've never tried but maybe you can create a no-argument constructor and call you function from there?


The article discuss 2 very nice solutions for this problem:

  1. "clean" junit with custom Runner (using interface but you could extend it with a custom annotation e.g. @BeforeInstance)
  2. Spring execution listeners as mentioned by Espen before.

Just use @BeforeClass:

@BeforeClass
public static void init() {
}

It doesn't make sense for init to be non-static because each test is run in a separate instance. The instance that init is run on would not match the instance of any test.

The only reason that you might want it to be non-static is to override it in subclasses, but you can do this with static methods too. Just use the same name, and only the subclass init method will be called.


UPDATE: Please see the comment by Cherry for why the suggestion below is flawed. (Am keeping the answer on here rather than deleting as the comment may provide useful information to others as to why this doesn't work.)


Another option worth considering if using dependency injection (e.g. Spring) is @PostConstruct. This will guarantee dependency injection is complete, which wouldn't be the case in a constructor:

@PostConstruct
public void init() {
    // One-time initialization...
}

참고URL : https://stackoverflow.com/questions/2825615/junit-before-class-non-static

반응형