让我们假设我们已经将以下代码段作为完整Java EE应用程序的一部分:
@Singleton
public class LoginService {
@Inject
private UserDAO userDAO;
protected boolean login(String username, String password){
// [...]
User user = userDAO.findByUsername(username);
// [...]
}
}
UserDAO是一个接口,该接口有一个名为DatabaseUserDAO的特定类实现,它被注入到userDAO字段中。
现在我要为登录方法e编写一个测试。 G。 testLoginSuccessfulIfLoginDataCorrect()
。但由于我不想依赖于数据库,我只想通过使用一个类来存根它。 public class TestUserDAO implements UserDAO
并注入此一个而不是注入的默认类。有什么可能实现它?我们还假设没有构造函数注入或其他方法来初始化字段。
答案 0 :(得分:2)
使用arquillian(http://arquillian.org/)以及mockito(http://site.mockito.org/)或其衍生产品之一:
示例(从实际代码修改为与您的类名有些匹配): (注意:这种部署生成仅适用于maven项目)
<style type="text/css">
.table {
width: 310px;
}
td:nth-child(1) {
width: 200px;
}
.table-responsive {
border: 1px solid;
width: 340px;
padding: 20px 30px 10px 10px;
border-radius: 5px;
}
td:nth-child(2),
td:nth-child(3),
td:nth-child(4) {
width: 30px;
}
tr:active {
color: orange;
}
td:hover {
background-color: #00BD9A;
}
</style>
请注意,您不需要以这种方式更改测试中的类,以便进行测试。
答案 1 :(得分:1)
嗯,这并不是秘密。
你有四种可能性。
为所有DAO(EJB)创建构造函数。
@Singleton
public class LoginService {
@Inject
private UserDAO userDAO;
LoginService (UserDAO userDAO) {
this.userDAO = userDAO;
}
}
为每个DAO创建一个集合。
@Singleton
public class LoginService {
@Inject
private UserDAO userDAO;
setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
}
使用默认访问
直接设置变量@Singleton
public class LoginService {
@Inject
UserDAO userDAO;
}
在你的测试中:
loginService.userDAO = userDAOMocked.
因此,您可以使用构造函数或setter模拟UserDAO并将其作为参数传递给LoginService测试。
另一个是by reflection(没有构造函数或setter),但我不喜欢这种方法......:
反射
public static void setPrivateField(Class<? extends Object> instanceFieldClass, Object instance, String fieldName, Object fieldValue) throws Exception {
Field setId = instanceFieldClass.getDeclaredField(fieldName);
setId.setAccessible(true);
setId.set(instance, fieldValue);
}
使用:
setPrivateField(loginService, "userDAO", userDAOMocked);