이번에는 "먼저 setUp() 메소드를 호출한다."를 구현했습니다.

public class TestCaseTest extends TestCase {

    WasRun test;
   
    public TestCaseTest(String methodName) {
        super(methodName);
    }
   
    protected void setUp() {
        test = new WasRun("testMethod");
    }
   
    public void testRunning(){
        test.run();
        assert test.wasRun == true;
    }
   
    public void testSetUp(){
        test.run();
        assert test.wasSetUp == true;
    }
   
    public static void main(String[] args) {
        new TestCaseTest("testRunning").run();
        new TestCaseTest("testSetUp").run();
    }
}

테스트 클래스는 이미 setUp()을 반영했지만, 사실 setUp()을 반영하기 전에 구현을 마치고, 리팩터링 하면서 방금 구현한 setUp()을 사용해서 테스트 클래스까지 간단하게 리팩터링을 했습니다.

import java.lang.reflect.Method;

public class TestCase {
   
    String methodName;

    public TestCase(String methodName) {
        this.methodName = methodName;
    }
   
    public void run() {
        setUp();
        try {
            Method method = this.getClass().getMethod(methodName, null);
            method.invoke(this, null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    protected void setUp() {}
}

Template Method 패턴을 사용해서, 하위 클래스에서 setUp()을 맘대로 구현할 수 있도록.. 했구요. run()에 워크 플로우를 정의했죠.

public class WasRun extends TestCase {

    boolean wasRun;
    boolean wasSetUp;
   
    public WasRun(String methodName) {
        super(methodName);
    }
   
    public void testMethod() {
        wasRun = true;
    }
   
    @Override
    protected void setUp() {
        wasRun = false;
        wasSetUp = true;
    }

}

WasRun에서도 역시 방금 구현한 setUp()을 사용해서 생성자를 좀 더 간단하게 했습니다.

'이번 장의 핵심 내용은 테스트 케이스들 간의 의존성을 없애기'였습니다. 지금처럼 매번 별도의 인스턴스를 만들기 때문에, 전역 변수를 사용하는 테스트가 아닌 이상 테스트 케이스들끼리 의존할 가능성은 거의 없게 됩니다.