如何在playframework中为功能测试设置数据库/夹具
我正在尝试测试我的控制器-Secure.java。我使用play的Fixtures类来设置数据库。不幸的是,当发出POST调用并调用控件的方法时,数据库结果是空的。但是,在测试方法中,我可以按预期检索数据 路线如何在playframework中为功能测试设置数据库/夹具,playframework,fixtures,Playframework,Fixtures,我正在尝试测试我的控制器-Secure.java。我使用play的Fixtures类来设置数据库。不幸的是,当发出POST调用并调用控件的方法时,数据库结果是空的。但是,在测试方法中,我可以按预期检索数据 路线 POST /login user.Secure.authenticate 控制器Secure.java: package controllers.user; import java.io.File; im
POST /login user.Secure.authenticate
控制器Secure.java:
package controllers.user;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Date;
import java.util.TimeZone;
import models.User;
import play.Logger;
import play.Play;
import play.data.validation.Required;
import play.libs.Crypto;
import play.mvc.Controller;
import play.mvc.Http;
import play.mvc.Util;
import play.utils.Java;
import mashpan.crawl.dropbox.DropboxCrawler;
import mashpan.security.Check;
import mashpan.utilities.*;
import controllers.Application;
/**
* a more or less exact copy of the secure implementation of play.
* - enhanced with a transport guarantee.
* - support for user authentification
*
* @author ra and Philip De Smedt
* @version 0.1
* @date 20/11/2011
*
*/
public class Secure extends TransportUriGuaranteeController {
public static void authenticate(@Required String username, String password, boolean remember) throws Throwable {
Logger.debug("[Secure] authenticate: "
+ "[username=" + (username == null ? "null" : username.toString()) + "]"
+ "[password=" + (password == null ? "null" : password.toString()) + "]"
+ "[remember=" + remember + "]"
);
// Check tokens
Boolean allowed = false;
User user = User.find("byEmail", username).first();
Logger.debug("[Secure.authenticate] "+"[user=" + (user == null ? "null" : user.toString()) + "]");
// try {
// // This is the deprecated method name
// allowed = (Boolean)Security.invoke("authentify", username, password);
// }
// catch (UnsupportedOperationException e )
// {
// // This is the official method name
// allowed = (Boolean)Security.invoke("authenticate", username, password);
// }
allowed = Security.authenticate(username, password);
if(validation.hasErrors() || !allowed) {
Logger.debug("[Secure] Authentication failed"
+ ", validationhasErrors()=" + validation.hasErrors()
+ ", allowed="+allowed
);
if(validation.hasErrors()) {
Logger.debug("[Secure] validation has errors!");
for(play.data.validation.Error e : validation.errors()) {
Logger.debug("[Secure] Error: "+"[e=" + (e == null ? "null" : e.toString()) + "]");
}
}
flash.keep("url");
flash.error("secure.error");
params.flash();
Application.index();
}
// Mark user as connected
session.put("email", username);
// Remember if needed
if (remember)
{
response.setCookie("rememberme", Crypto.sign(username) + "-" + username, "30d");
}
// Save last login time and redirect to the original URL (or /)
User u = User.find("byEmail", username).first();
u.lastLogin = new Date();
u.save();
Logger.debug("[Secure] Successfully authenticated user. Redirecting...");
redirectToOriginalURL();
}
public static class Security extends Controller {
/**
* Extend Play!s security mechanism to authenticate against
* the User object.
*/
public static boolean authenticate(String email, String password) {
Logger.debug("[Secure.Security.authenticate] "
+ "[email=" + (email == null ? "null" : email.toString()) + "]"
+ "[password=" + (password == null ? "null" : password.toString()) + "]");
User user = User.find("byEmail", email).first();
List<User> users = User.<User>findAll();
Logger.debug("[Secure.Security] # of users found="+users.size());
for(User u : users) {
Logger.debug("[Secure.Security] "+"[u=" + (u == null ? "null" : u.toString()) + "]");
}
if (user == null) {
Logger.debug("[Secure.Security] Could not find user, authentication failed!");
return false;
}
if (user.confirmationCode.length() != 0) { //user not confirmed yet
Logger.debug("[Secure.Security] User not confirmed yet, authentication failed!");
return false;
}
return user.isThisCorrectUserPassword(password);
}
public static boolean check(String check) {
if ("isConnected".equals(check)) {
return Security.isConnected();
}
return false;
}
/**
* This method returns the current connected username
* @return
*/
public static String connected() {
return session.get("email");
}
/**
* Indicate if a user is currently connected
* @return true if the user is connected
*/
public static boolean isConnected() {
return session.contains("email");
}
/**
* This method is called after a successful authentication.
* You need to override this method if you with to perform specific actions (eg. Record the time the user signed in)
*/
static void onAuthenticated() { }
/**
* This method is called before a user tries to sign off.
* You need to override this method if you wish to perform specific actions (eg. Record the name of the user who signed off)
*/
static void onDisconnect() { }
/**
* This method is called after a successful sign off.
* You need to override this method if you wish to perform specific actions (eg. Record the time the user signed off)
*/
static void onDisconnected() { }
/**
* This method is called if a check does not succeed. By default it shows the not allowed page (the controller forbidden method).
* @param profile
*/
static void onCheckFailed(String profile) {
forbidden();
}
}
}
堆栈跟踪
DEBUG 232 :play#debug - [FunctionalSecureTests] [user=User [first_name=Mash, last_name=Pan, email=mashpantester@gmail.com, signupDate=2012-03-08 01:00:00.0, passwordHash=$2a$10$L6IdeDhMGe1T7IbtSDd.6uLOvhHk7IoAzRzGzNlk8Cm4WWyWCbIp., isAdmin=false, confirmationCode=, activationSent=true, recoverPasswordCode=null, lastLogin=null, referralCode=null, [id=1]]]
DEBUG 232 :play#debug - [Secure] authenticate: [username=mashpantester@gmail.com][password=chickenrunfasteriffedup][remember=false]
DEBUG 232 :play#debug - [Secure.authenticate] [user=null]
DEBUG 232 :play#debug - [Secure.Security.authenticate] [email=mashpantester@gmail.com][password=chickenrunfasteriffedup]
DEBUG 232 :play#debug - [Secure.Security] # of users found=0
DEBUG 232 :play#debug - [Secure.Security] Could not find user, authentication failed!
DEBUG 232 :play#debug - [Secure] Authentication failed, validationhasErrors()=false, allowed=false
您的功能测试在将在测试结束时结束的事务中运行。因此,在测试完成之前,您在此事务中所做的一切都不会提交到数据库。因此,在这种情况下,您可以使用作业仅为设置创建新事务
@Before
public void setUp() throws Exception {
new Job() {
@Override
public void doJob() throws Exception {
Fixtures.deleteDatabase();
Fixtures.loadModels("testusers.yaml");
Cache.clear();
}
}.now().get();
}
您的功能测试在将在测试结束时结束的事务中运行。因此,在测试完成之前,您在此事务中所做的一切都不会提交到数据库。因此,在这种情况下,您可以使用作业仅为设置创建新事务
@Before
public void setUp() throws Exception {
new Job() {
@Override
public void doJob() throws Exception {
Fixtures.deleteDatabase();
Fixtures.loadModels("testusers.yaml");
Cache.clear();
}
}.now().get();
}
只需添加:
JPA.em().getTransaction().commit();
在Fixtures.loadModels之后添加:
JPA.em().getTransaction().commit();
在Fixtures.loadModels之后