我有一个具有getUser函数的bean,它返回当前登录的用户,或者如果变量user为空则找到一个。
我的bean中是否有糟糕的设计,或者我应该只创建一个setUser函数?我不确定正确的方法是什么。
这是我对该AuthorizationBean的测试:
public class AuthorizationBeanTest {
private AuthorizationBean authorizationBean;
@Mock
User user;
@Mock
UserDao userDao;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
authorizationBean = new AuthorizationBean();
//I want to set the user to the mocked user so I can test the logout function
}
@Test
public void doLogoutTest() {
assertNotNull(authorizationBean.getUser());
assertEquals("/login.xhtml?faces-redirect=true", authorizationBean.doLogout());
assertNull(authorizationBean.getUser());
}
}
以下是bean的代码:
@ManagedBean(name = "authBean")
@SessionScoped
public class AuthorizationBean implements Serializable{
//Data access object for the users
@Inject
UserDao userDao;
private User user; // The JPA entity.
public User getUser() {
if (user == null) {
user = (User) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user");
if (user == null) {
Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
if (principal != null) {
user = userDao.findByEmail(principal.getName()); // Find User by j_username.
}
}
}
return user;
}
/**
* Function that handles the logout
* @return Redirect string that points to the login page
*/
public String doLogout() {
// invalidate the session, so that the session is removed
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
user = null;
// return redirect to login page
return "/login.xhtml?faces-redirect=true";
}
}
答案 0 :(得分:1)
您可以在@Before方法中模拟用户,如下所示:
Mockito.when(authorizationBean.getUser()).thenReturn(user);
为此,您还需要模拟AuthorizationBean类。
你也可以省略MockitoAnnotations.initMocks(this);使用Mockito运行程序运行整个测试的invokation,将此注释放在测试类上:
@RunWith(MockitoJUnitRunner.class)
更新:但是,您无法测试AuthorizationBean确实嘲笑它。你的bean中有几个静态方法调用,你可以用PowerMock来模拟它们,但是使用PowerMock也是审查设计的难闻气味。
更新2 : 使用PowerMock,您实际上可以执行以下操作:
PowerMockito.mockStatic(FacesContext.class);
PowerMockito.when(FacesContext.getCurrentInstance()).thenReturn(context);
上下文是另一个模拟,然后用你的模拟用户填充会话地图。
更新3 :不要忘记运行测试用例,然后使用@RunWith(PowerMockRunner.class)。你可以查看一个更详细的例子here,但如果将来链接被破坏,上面的说明应该已经给你一个良好的开端。
答案 1 :(得分:1)
我通常做的是,为了简单起见,我将字段包设为私有,并使用guava's @VisibleForTesting
@VisibleForTesting User user; // The JPA entity.
答案 2 :(得分:1)
您可以使用好的(或不喜欢的)旧java.reflection
包来设置私有字段。
Field userField = authorizationBean.getClass().getDeclaredField("user");
userField.setAccessible(true);
userField.set(authorizationBean, someUser);
在测试范围内,我认为它并不像它看起来那么糟糕......