问题
I wrote a functional test to check adding items to a shopping cart.For a user to be able to add items to cart,he needs to login.So,I created a method to login the user and another method to add the item.Before and after the addtocart method in test,I am checking the size of content of cart.The addtocart functionality works without any problem when I run the app in dev mode(I can check the db too-which is postgres and not an in memory db).The addtocart fails in test.
the controller method which adds item to cart
public static void addItemToCart(Long productId,Long cartId,String quantity) {
Product product = Product.findById(productId);
ShopCart cart = ShopCart.findById(cartId);
int qty = Integer.parseInt(quantity);
CartItem cartItem = new CartItem(product,qty);
cart.addItem(cartItem);
cart.save();
System.out.println("Controller::addItemToCart()::cart id="+cart.id+" has="+cart.cartItems.size()+" items);
}
my test method is
@Test
public void testUserCanAddItemsToCart() {
Fixtures.loadModels("data.yml");
User user = User.find("byEmail","user@shop.com").first();
loginAsCustomer("user@shop.com","userpass");
ShopCart usercart = new ShopCart(user);
usercart.save();
System.out.println("BEFORE ADD::usercart="+usercart.id+" has :"+usercart.cartItems.size()+" items");
assertTrue(usercart.cartItems.size()==0);
addItemsToCart(usercart);
System.out.println("AFTER ADD::usercart="+usercart.id+" has :"+usercart.cartItems.size()+" items");
assertFalse(usercart.cartItems.size()==0);//why does this fail?
}
private Response addItemsToCart(ShopCart cart) {
Product pdt = Product.find("byIsbn","654-0451160522").first();
assertNotNull(pdt);
System.out.println("addItemsToCart():BEFORE ADD cart="+cart.id+" has="+cart.cartItems.size());
Map<String,String> addtocartParams = new HashMap<String,String>();
addtocartParams.put("cartId", cart.id.toString());
addtocartParams.put("quantity", "2");
String addtocarturl = "/items/addtocart/"+pdt.id.toString();
Response response = POST(addtocarturl,addtocartParams);
System.out.println("addItemsToCart():AFTER ADD cart="+cart.id+" has="+cart.cartItems.size());
return response;
}
The console output I get is
BEFORE ADD::usercart=48 has :0 items
addItemsToCart():BEFORE ADD cart=48 has=0
Controller::addItemToCart()::cart id=48 has=1 items
addItemsToCart():AFTER ADD cart=48 has=0
AFTER ADD::usercart=48 has :0 items
Here, in the controller method, the cart instance (of id=48) has 1 item after it is saved to db.But in the test method ,the cart instance of same id has 0 content.
I commented out the assertFalse method and retrieved the cart from db using the cartId.Even then the cart of same id has 0 content.I can't understand why this is happening..can anyone shed some light?
//test method body ..modified
ShopCart cart = ShopCart.findById(usercart.id);
System.out.println("AFTER ADD::cart="+cart.id+" has :"+cart.cartItems.size()+" items");
assertFalse(cart.cartItems.size()==0);//why does this fail?
回答1:
It fails because the cart instance used by your test method and the cart instance used by the addItemToCart method are different. Each transaction has its own instance of the entity. And JPA doesn't automagically refresh an entity when some other transaction updates the row mapped by this entity.
You should reload the cart from the database after addItemsToCart has been called to check if something has been added to the cart in database.
回答2:
I am a slave to object-oriented thinking, so what I'm wondering is, have you thought about making addItemsToCart() a method of your ShopCart class? I'm envisioning something like:
...
ShopCart usercart = new ShopCart(user);
usercart.addItemsToCart(pdt);
usercart.save();
String addtocarturl = "/items/addtocart/"+pdt.id.toString();
Response response = POST(addtocarturl,addtocartParams);
return response;
It's just easier for me to think about making (or retrieving) a ShopCart object, modifying it, and putting it in the database. That's how I would avoid this.
回答3:
I had the same issue and adding JPA.em().clear() in my test before I get the model from the database solved this issue for me.
来源:https://stackoverflow.com/questions/7593802/functional-test-in-playframework-fails-when-adding-items-to-cart