【问题标题】:proper way of writing FunctionalTest in playframework在游戏框架中编写功能测试的正确方法
【发布时间】:2012-03-01 04:48:51
【问题描述】:

在为基于 play1.2.4 的 webapp 编写 FunctionalTest 时,我对如何正确编码有点困惑。困惑在于所涉及的事务边界。我在某处读到每个测试都有自己的事务。

在我的应用中,用户可以登录并将一些商品添加到购物车。然后他可以提供一个地址,以便将商品发送给他。

我创建了如下的私有辅助方法

private Cart buyItemsAsCustomer(String email,String pass) {
    User user = User.find("byEmail", email).first();
    //login
    Response loginResponse = loginAsUser(email,pass);
    Cart cart = new Cart(user);
    cart.save();
    addItemsToCart(cart.id);
    return cart;
}
private Response loginAsUser(String email,String password) {
    Map<String,String> loginUserParams = new HashMap<String,String>();
    loginUserParams.put("username", email);
    loginUserParams.put("password", password);
    Response response = POST("/login",loginUserParams); 
    return response;
    }

private Response addItemsToCart(Long cartId) {
    Cart cart = Cart.findById(cartId);
    Item item = Item.find("byIsbn","978-0451160522").first();
    Map<String,String> addtocartParams = new HashMap<String,String>();
    addtocartParams.put("cartId", cart.id.toString());
    addtocartParams.put("quantity", "2");
    String addtocarturl = "/items/addtocart/"+item.id.toString();
    Response response = POST(addtocarturl,addtocartParams);
    cart.refresh();//without this the assertion about number of items in cart fails!
    return response;
}

private Map<String,String> createAddressParams(){
    Map<String,String> addressParams = new HashMap<String,String>();
    addressParams.put("addressline1", "1123,xx street");
    addressParams.put("state", "new york");
    addressParams.put("country", "US");
    return addressParams;
}

最后我编写了 FunctionalTest,它调用这些辅助方法中的每一个来执行任务,然后执行断言

@Test
public void testCustomerCanAddAddress() {
    Fixtures.loadModels("data.yml");
    assertTrue(Address.findAll().size()==0);
    Cart joncart = buyItemsAsCustomer("jon@gmail.com","jon");
    assertFalse(jonart.cartItems.size()==0);
    Map<String,String> addressParams = createAddressParams();
    POST("/items/address/"+joncart.customer.getId().toString(),addressParams);
    assertTrue(Address.findAll().size()==1);
}

运行它会产生一个

A java.lang.RuntimeException has been caught, java.util.concurrent.ExecutionException: play.exceptions.JavaExecutionException@在

POST("/items/address/"+joncart.customer.getId().toString(),addressParams);

我认为这是由于某些事务边界问题而发生的,但我不确定..有人可以帮我纠正这个问题吗?..我真的很想得到一些关于在这种情况下应该如何编写测试的帮助..

我已经粘贴了堆栈跟踪here

【问题讨论】:

    标签: java transactions playframework playframework-1.x


    【解决方案1】:

    你的测试很奇怪,因为你混合了 http 调用和模型调用。功能测试纯粹是 http 调用。你测试你的控制器层

    如果您需要一些模拟数据,您必须在另一个事务中创建它们,对我来说最简单的方法是使用特定方法的作业。如果您想检索数据以确保您的测试通过,也是如此。

    @Before
    public void cleanUp() throws Exception {
        new Job() {
            @Override
            public void doJob() throws Exception {
                Fixtures.deleteDatabase();
                Fixtures.loadModels("data.yml");
            }
    
        }.now().get();
    }
    

    【讨论】:

      【解决方案2】:

      java.util.concurrent.ExecutionException 不一定是由事务引起的。我的功能测试出现了这个异常,因为我没有在 routes 文件中为我的控制器方法指定正确的 POST 路由。

      但是,如果我需要使用修改数据库的 POST 请求并且需要在功能测试方法中检查结果,我使用

      Response response = POST("address/to/my/controller/", params);
      
      JPAPlugin.closeTx(false);
      JPAPlugin.startTx(false);
      
      // Check here that the changes to the database are correct!
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-13
        • 1970-01-01
        • 1970-01-01
        • 2013-02-26
        • 1970-01-01
        相关资源
        最近更新 更多