2014-07-16 69 views
1

我有一個單元測試,我想測試一個特定的運行時異常發生。但是,似乎數據庫更改不會在測試類中的每個測試之間回滾,這是正常行爲(並且適用於所有其他測試)。Play Framework 2(Java)中的單元測試不回滾測試之間的變化

我試圖創建一個可以在下面看到的問題的最小例子。當運行TestTest時,當您運行第二次測試時,您會從setUp()方法中調用Unique index or primary key violationMyClass.create("abc")

問題似乎需要這種特定的設置:即使最輕微的變化也會使問題消失,如果交換兩個測試的名字;如果試圖簡化某些調用方法的方法等級;或者使用不是@Entity的類或不使用@Transactional的方法。

我簡直不明白這一點。誰能幫忙?

我正在使用Play Framework 2.2(Java版本)。

單元測試類:

public class TestTest extends WithApplication { 
    @Before 
    public void setUp() { 
     start(fakeApplication(inMemoryDatabase(), fakeGlobal())); 
     MyClass.create("abc"); 
    } 

    @Test(expected = RuntimeException.class) 
    public void test1() { 
     MyClass c = MyClass.create("blabla"); 
     c.foo(); 
    } 

    @Test 
    public void test2() { 
     assert(true); 
    } 
} 

的MyClass實現:

@Entity 
public class MyClass extends Model { 

    @Id 
    public Long id; 

    @Column(unique = true) 
    public String name; 

    private MyClass(String name) { 
     this.name = name; 
    } 

    public static MyClass create(String name) { 
     MyClass c = new MyClass(name); 
     c.save(); 
     return c; 
    } 

    @Transactional(type = TxType.REQUIRED) 
    public void foo() { 
     Bar bar = new Bar(); 
     bar.foo(); 
    } 

    class Bar { 
     void foo() { 
      throw new RuntimeException(); 
     } 
    } 
} 
+0

其他測試是否也擴展'WithApplication'? –

+0

是的,所有這些都可以。 – plade

+0

你可以在沒有捕獲異常的情況下嘗試嗎?測試不應該捕獲異常;所有的測試運行器框架都足夠聰明,可以通過測試來拋出異常 –

回答

0

遊戲沒有做到這一點。你必須手動回滾數據庫中的變更:(在我的項目中,使用ebean,我創建了一個超類,爲我完成了這項工作,你可以看看這個gist =>https://gist.github.com/asouza/1b415e5582c7b9fff9b0

+0

聽起來很奇怪。如果我在第一次測試中刪除'expected = RuntimeException.class'並註釋掉'c.foo()'(它產生了RuntimeException)這行,那麼這兩個測試都會通過。因此,似乎數據庫更改實際上在沒有RuntimeException的情況下回滾。 – plade