2014-07-16 40 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