听取了论坛老哥的建议:把所有测试功能都自动化起来。所以现在接着练习JUnit4。
今天测试登录功能,核心代码如下:
@Autowired
UserMapper userMapper;
@Autowired
HttpServletRequest request;
/**
* 用户登录操作。将用户存入session
*
* @param userName 用户名称
* @param pwd 用户密码
* @return
*/
@Override
public User login(String userName, String pwd) {
HttpSession session = request.getSession();
//MD5 加密后再与数据库中的密码进行比对
pwd = MD5Util.md5Pwd(pwd);
// 通过userName和pwd得到数据库中对应的记录,
User user = userMapper.login(userName, pwd);
if (user != null) {
user.setPwd(null);
// 得到user对象, 存入Session中
session.setAttribute("user", user);
}
return user;
}
然后写了一个JUnit测试
import cn.edu.zzuli.BlogApplication;
import cn.edu.zzuli.bean.User;
import cn.edu.zzuli.util.Msg;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BlogApplication.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class LoginControllerTest {
@Autowired
LoginController loginController;
@Autowired
HttpServletRequest request;
@Test
public void login() {
Msg msg = (Msg) loginController.login("001001", "123456");
System.out.println(msg);
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
System.out.println(user);
}
}
然后报错:
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
大意就是无法得到“HttpServletRequest request;”也就是说自动注入除了问题。
网上有的话是因为request是个单例,所以无法注入,可是这种情况应该只在高并发的情况下才可能会出现,于是我排除了这种情况。
然后有的建议我使用
@WebAppConfiguration
试了一下,又报了一个很有意思的错。
java.lang.IllegalStateException: @WebAppConfiguration should only be used with @SpringBootTest when @SpringBootTest is configured with a mock web environment. Please remove @WebAppConfiguration or reconfigure @SpringBootTest.
大意是:应该只用一个注解,要么删掉@WebAppConfiguartion,要么SpringBootTest中的 webEnvironment 变量就别用。
我第一次果断删掉了@WebAppConfiguartion,然后发现代码就回到第一次出错的代码,于是我把SpringBootTest中webEnvironment变量删掉后,再次启动,成功。
小结一下:
//刚开始注入失败的注解
@RunWith(SpringRunner.class)
@SpringBootTest(classes=BlogApplication.class,webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT)
//第一次修改都的错误注解,Spring在你启动JUnit的时候告诉你两者只能有一个。
@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = BlogApplication.class,webEnvironment =SpringBootTest.WebEnvironment.RANDOM_PORT)
// 最后成功在JUnit4中的登录中注入request的注解
@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = BlogApplication.class)