2011-11-02 5 views
3

두 가지 테스트와 블록을 추가하는 특성이 있습니다. 구체적인 인스턴스의 @Before 블록은 특성의 것보다 먼저 실행됩니다. 아차,이 내가 데이터베이스 테이블은 다음기구를 삽입 절단 할 수 없음을 의미 :주문 방법 @ 이전 방법

trait DatabaseTest { 
    @Before 
    def truncate() { 
    // "TRUNCATE %s".format(tableName) 
    } 

    def tableName 
} 

class PersonasTest extends DatabaseTest { 
    @Before 
    def addPersona() { 
    // "INSERT INTO %s VALUES (...)".format(tableName) 
    } 


    @Test 
    def testRejectsInsertWhenAlreadyInTable() { 
    // "INSERT INTO %s VALUES (...)".format(tableName) 
    } 

    def tableName = "personas" 
} 

testRejectsInsertWhenAlreadyInTable 실행 순서가되기 때문에 항상 성공합니다

  • addPersona
  • truncate
  • testRejectsInsertWhenAlreadyInTable

서브 클래스에 너무 많은 제약 조건을 부과하지 않고 @Before 블록을 정렬하는 적절한 방법? 나는 항상 특성에서 truncate을 선언 할 수 있었고, 서브 클래스에서 @Before 메소드를 가졌지 만, 모든 하위 클래스가 그 truncate 메소드를 호출하도록 기억해야합니다.

Scala 2.9.0.1에서 JUnit 4.10 사용.

답변

4

이 일을 올바른 방법은, @Rule를 사용하기 전에과 (자바 문법) 타입 동작 후 @ExternalResource을 확장하는 것입니다

@Rule 
public ExternalResource resource= new ExternalResource() { 
     @Override 
     protected void before() throws Throwable { 
       myServer.connect(); 
     }; 

     @Override 
     protected void after() { 
       myServer.disconnect(); 
     }; 
}; 

당신 체인 위해 여러 @Rule은을 사용하여 위해 함께 s의 수 @RuleChain (4.10 도입), 다시 자바 구문 :

@Rule 
public TestRule chain= RuleChain 
         .outerRule(new LoggingRule("outer rule") 
         .around(new LoggingRule("middle rule") 
         .around(new LoggingRule("inner rule"); 

은주의가있다. 스칼라에서 공용 필드를 지정할 수 없습니다 (공용 필드는 접근 자 메서드로 래핑되고 필드 자체는 비공개가됩니다). JUnit은 @Rule이 public 필드에 적용되는지 확인합니다. 메소드뿐만 아니라 필드에 @Rule을 적용 할 수 있도록 JUnit 코드를 변경하는 수정.

이 문제는 (나에 의해) 수정되었으며 마스터에 병합되었습니다.하지만 불행히도 아직 출시되지 않았습니다. 4.11의 일부가됩니다. 따라서 4.11-SNAPSHOT을 사용하거나 4.10 릴리스를 다운로드하고 patch for @Rule을 적용하는 두 가지 옵션이 있습니다. 의 JUnit 스냅 샷의 repo는

trait DatabaseTest { 
    def truncate(): TestRule = { 
     new ExternalResource() { 
      override def before() = { 
       // "TRUNCATE %s".format(tableName) 
      } 
     } 
    } 

    def extra(): TestRule = { 
     // return a no-op rule 
    } 

    @Rule def testRule() = new RuleChain(truncate(), extra()) 
    def tableName 
} 

class PersonasTest extends DatabaseTest { 
    def extra(): TestRule { 
     new ExternalResource() { 
      override def before() = { 
       // "INSERT INTO %s VALUES (...)".format(tableName) 
      } 
     } 
    } 

    @Test 
    def testRejectsInsertWhenAlreadyInTable() { 
    // "INSERT INTO %s VALUES (...)".format(tableName) 
    } 

    def tableName = "personas" 
} 
+0

:

스칼라 코드는 같을 수 있을까? build.xml https://github.com/KentBeck/junit/blob/master/build.xml#L306에 따르면 https://oss.sonatype.org/content/repositories/snapshots에서 찾아야하지만 4.9 만 .1 거기에있다. –

+0

실수가 있었다고 생각합니다. 야간 빌드는 4.11-SNAPSHOT보다는 4.9.1 인 것 같습니다. 나는 관리자에게 이메일을 보냈습니다. –

+0

4.9.1-SNAPSHOT은 ChainRule을 포함하지 않으므로 4.11보다는 4.9.1 일 가능성이 높습니다. 도와 주셔서 정말로 고맙습니다! –

0

에 대해 어떻게 : 결국

abstract class DatabaseTest { 

    // "TRUNCATE %s".format(tableName) 

    def tableName 
} 

class PersonasTest extends DatabaseTest { 
    @Before 
    def addPersona() { 
    // "INSERT INTO %s VALUES (...)".format(tableName) 
    } 

    @Test 
    def testRejectsInsertWhenAlreadyInTable() { 
    // "INSERT INTO %s VALUES (...)".format(tableName) 
    } 

    def tableName = "personas" 
} 

, PersonasTest것은-ADatabaseTest.