MVC框架单元测试java



我的任务是为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的实际设置进行比较。

单独使用给定的代码,一个工作的测试样本实际上并不实用。

最新更新