我的任务是为MVC框架创建Unit Testing
。我试着在谷歌上搜索它,但我看到的不是MVC,而是Spring MVC
我对JUnit测试的基本语法有一些想法
因为我是单元测试的新手,所以我只知道那么多
所以请给我一个关于如何对MVC进行单元测试的示例。我真的必须设置Required Dependencies with Maven
吗
更新:
/**
* Servlet implementation class LoginController
*/
public class LoginController extends HttpServlet {
/**
* Determines the version number for this serializable class.
*/
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LoginController() {
super();
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doGet( HttpServletRequest request, HttpServletResponse response )
{
Logger log = Logger.getLogger(getClass());
HttpSession session = request.getSession();
String username = request.getParameter( SessionUtility.USERNAME );
String password = request.getParameter( SessionUtility.PASSWORD );
RequestDispatcher rd = null;
boolean withError = false;
if( request.getParameter( RegistrationController.UPDATE_PASSWORD_BUTTON ) != null &&
request.getParameter( RegistrationController.UPDATE_PASSWORD_BUTTON ).equalsIgnoreCase( "updatepass" ) )
{
String userId = request.getParameter( "userid" );
String newPassword = request.getParameter( "newpassword" );
String oldPassword = request.getParameter( "oldpassword" );
UsersDAO userDAO = new UsersDAO();
if( userDAO.isUserPasswordMatch( userId, oldPassword ) )
{
userDAO.setNewPassword( newPassword, userId );
request.getSession().setAttribute( ProntoUtility.SUCCESS_MESSAGE, "Password successfully updated." );
}
else
{
request.setAttribute( ProntoUtility.ERROR_MESSAGE, "Old password did not match." );
}
rd = request.getRequestDispatcher( ProntoUtility.STATE_TABLE_DISPLAY );
try
{
rd.forward( request, response );
}
catch( ServletException e )
{
log.error( "ServletException" );
}
catch( IOException e )
{
log.error( "IOException" );
}
return;
}
else if( session.getAttribute( SessionUtility.SESSION_NAME ) != null )
{
session.getAttribute( SessionUtility.SESSION_TYPE );
rd = request.getRequestDispatcher( ProntoUtility.STATE_TABLE_DISPLAY );
withError = true;
}
else if( ( username == null || password == null ) && !withError )
{
rd = request.getRequestDispatcher( ProntoUtility.LOGIN_PAGE );
withError = true;
}
else if( ( username == "" || password == "" ) && !withError )
{
request.setAttribute( ProntoUtility.ERROR_MESSAGE, "Please fill-up the required fields." );
rd = request.getRequestDispatcher( ProntoUtility.LOGIN_PAGE );
withError = true;
}
else if( !withError )
{
String encryptedPassword = PasswordEncryption.encryptPassword(password);
UsersDAO usersDAO = new UsersDAO();
UsersModel login = usersDAO.getUsernamePassword( username, encryptedPassword );
if( login != null )
{
String usernameDB = login.getUsername();
String passwordDB = login.getPassword();
String teamId = login.getTeamId();
String userName = login.getUsername();
int userId = login.getUserId();
if( usernameDB.equals( username ) && passwordDB.equals( encryptedPassword ) )
{
session.setAttribute( SessionUtility.USERNAME, userName );
session.setAttribute( SessionUtility.SESSION_TEAM, teamId );
session.setAttribute( SessionUtility.SESSION_ID, userId );
session.setAttribute( SessionUtility.SESSION_NAME, usernameDB );
session.setAttribute( SessionUtility.SESSION_TYPE, login.getType() );
session.setAttribute( SessionUtility.SESSION_PROJECT, login.getProjectId() );
session.setAttribute( SessionUtility.SESSION_PROJECT_NAME, login.getProjectName() );
rd = request.getRequestDispatcher( ProntoUtility.STATE_TABLE_DISPLAY );
withError = true;
}
else if( !withError )
{
request.setAttribute( ProntoUtility.ERROR_MESSAGE, "Incorrect username/password." );
rd = request.getRequestDispatcher( ProntoUtility.LOGIN_PAGE );
withError = true;
}
}
else if( !withError )
{
request.setAttribute( ProntoUtility.ERROR_MESSAGE, "Incorrect username/password." );
rd = request.getRequestDispatcher( ProntoUtility.LOGIN_PAGE );
withError = true;
}
}
try
{
if( withError == true )
rd.forward( request, response );
}
catch( ServletException e )
{
log.debug( "Unable to forward to requested dispatcher", e );
}
catch( IOException e )
{
log.debug( "Null forward request", e );
}
return;
}
/**
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
@Override
public void doPost( HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse )
{
doGet( paramHttpServletRequest, paramHttpServletResponse );
}
}
我添加了一个我正在处理的项目的示例控制器。
如何使用junit进行单元测试
如果你现在对自己说:"但我想测试MVC,而不是学习单元测试在理论上是如何工作的",那么答案是:
单元测试意味着在不受其他类干扰的情况下测试单个类或单元(在Java中是一个类)。当然,一个应用程序有多个类,它们相互使用。但是,使用mock对象,您可以为测试类提供对象,这些对象只是提供类所需的必要东西,而不是测试类在运行时使用的类的对象。模拟对象看起来和感觉都像真实对象。您可以确切地指定它们将在方法调用时返回的值。
这样,您就可以在没有任何其他类干扰的情况下测试单个类。因此,可以很容易地检测到问题(只有一个可能的来源)。通常,您为每个类编写一个单元测试用例。
由于这是一个按类的解决方案,所以使用哪个框架基本上并不重要。但有些框架支持测试(完全经过单元测试,支持依赖注入),而另一些框架则不支持(例如,许多单例)。
如何测试给定的类
我们只为一个类编写一个JUnit测试用例(好的IDE支持您这样做)。如果这个类扩展了另一个而不是的类,那么这就像为一个只有Object作为父类的类编写测试一样容易。你不必测试父母的方法,只需要测试你自己的方法。理想情况下,构造函数没有副作用。它只是将对象初始化为稳定状态,但不启动其他操作。这样,您甚至可以对在自己的代码库中扩展类的类进行单元测试。由于父类只用于构造函数(可能还有类中的一些方法调用),因此可以集中测试子类的方法。
当您为每个类编写单元测试时,父类也是如此。如果问题在父类中,相关的测试用例会发现问题(如果写得好的话)。
回到你的问题:首先,没有什么比测试MVC更好的了。MVC是一种设计模式。第二,在单元测试中,你不测试类的交互(寻找功能测试)。
功能测试
功能测试确实测试组件的某个子集的交互作用。一个功能测试可以测试CMS中的登录。对于一个登录,需要大量的类。在测试时间线中,首先运行单元测试,然后运行功能测试(因为这些测试需要工作类)。每当出现问题时,必须在解决问题后重新运行该过程。
摘要
您要求提供一个样本来测试"MVC"。正如前面所解释的,没有什么比测试MVC更像它是一种模式了。由于显示的servlet有一个巨大的方法(没有说明它的结构有多好——或者是否有多好)和一个只调用它的方法,所以它的构建对测试不是很友好。此外,该方法受到保护,因此您需要进行白盒测试,而不是黑盒测试。
功能测试对您来说可能很有趣,因为这将允许您实际使用多个类并测试它们的交互。例如,如果您的类执行XYZ并更改类B的设置,那么您可以通过调用类的方法来测试交互,然后将预期结果与类B的实际设置进行比较。
单独使用给定的代码,一个工作的测试样本实际上并不实用。