2012-03-01 2 views
3

При написании FunctionalTest для webapp на основе play1.2.4, я был немного смущен относительно того, как правильно его кодировать. Путаница касается задействованной границы транзакции. Я где-то читал, что каждый тест имеет свою собственную транзакцию.надлежащий способ написания FunctionalTest в playframework

В моем приложении пользователь может войти и добавить некоторые предметы в корзину. Затем он может дать адрес, чтобы предметы могли быть отправлены ему.

Я создал частные вспомогательные методы, как ниже

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("[email protected]","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); 

Я думаю, что это происходит из-за некоторых проблем с границей транзакций, но я не уверен ... Может кто-то, пожалуйста, помогите мне исправить это? .. Мне действительно нужна помощь в том, как тест должен быть написан в этом случае. .

Я вставил StackTrace here

ответ

2

java.util.concurrent.ExecutionException не обязательно, вызванных операциями. У меня есть это исключение для моего функционального теста, потому что я не указал правильный маршрут 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! 
3

Ваш тест странные, потому что вы смешиваете HTTP вызовы и модели звонки. Функциональный тест - это чисто http-звонки. Вы тестируете свой уровень контроллеров

Если вам нужны некоторые данные, вы должны создать их в другой транзакции, самый простой способ сделать это для меня - использовать задание по определенному методу. То же самое, если вы хотите получить данные для обеспечения прохождения теста.

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

    }.now().get(); 
} 
Смежные вопросы