0

我的任务是Unit Testing为 MVC 框架工作。我试图在谷歌上搜索它,但我看到的不仅仅是 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 );
    }
}

我添加了我正在处理的项目的示例控制器。

4

1 回答 1

0

如何使用junit进行单元测试?

如果你现在说自己:“但我想测试 MVC,而不是学习单元测试在理论上是如何工作的”,那么这里是回复:

单元测试意味着在不受其他类干扰的情况下测试单个类或单元(在 Java 中它是一个类)。当然,一个应用程序有不止一个类,它们相互使用。但是使用模拟对象,您可以提供测试类对象,这些对象只提供类需要的必要东西,但不是测试类在运行时使用的类的对象。模拟对象看起来和感觉就像真实的对象。您可以准确指定它们应在调用什么方法时返回什么值。

这样,您就可以测试单个类,而不会受到任何其他类的干扰。因此可以很容易地检测到问题(只是一种可能的来源)。通常你为每个类编写一个单元测试用例。

由于这是一个按类解决方案,因此您使用哪个框架基本上并不重要。但是有些框架支持测试(完全经过单元测试,支持依赖注入),而另一些则不支持(例如很多单例)。

如何测试给定的课程?

好吧,只为一个类编写一个 JUnit 测试用例(好的 IDE 支持你)。如果这个类扩展了另一个不是您的代码的类,那么这就像为只有 Object 作为父类的类编写测试一样容易。您不必测试父母的方法,只需您自己的方法。理想情况下,构造函数没有副作用。它只是将对象初始化为稳定状态,但不启动其他操作。这样,您甚至可以对在您自己的代码库中扩展类的类进行单元测试。由于父类仅用于构造函数(可能还有类中的一些方法调用),因此您可以集中测试子类的方法。

当您为每个类编写单元测试时,您也为父类编写单元测试。如果问题出在父类,相关的测试用例会发现(如果写得好)。

回到您的问题:首先,没有什么可以测试 MVC。MVC 是一种设计模式。其次在单元测试中,您不测试类的交互(寻找功能测试)。

功能测试

功能测试确实测试了某个组件子集的交互。一项功能测试可以测试 CMS 中的登录。对于一次登录,需要多个类。在测试时间线中,您首先运行单元测试,然后是功能测试(因为这些需要工作类)。每当某些事情不起作用时,您必须在解决问题后重新运行该过程。

概括

您要求提供一个样本来测试“一个 MVC”。如前所述,没有什么比测试 MVC 更重要的了,因为它是一种模式。由于所示的 servlet 有一个巨大的方法(没有评论它的结构是否良好)和一个只调用它的方法,因此它的构建对测试不太友好。此外,该方法受到保护,因此您需要进行白盒测试而不是黑盒测试

功能测试可能会让您感兴趣,因为它可以让您实际使用多个类并测试它们的交互。例如,如果你的类做了 XYZ 并更改了 B 类的设置,那么你可以通过调用你的类的方法来测试交互,然后将预期结果与 B 类的实际设置进行比较。

仅使用给定的代码,工作测试样本并不实用。

于 2013-07-29T16:34:35.623 回答