0

私の仕事はUnit Testing、MVC フレームワークを作成することです。Google で検索しようとしましたが、MVC だけでなく、Spring MVC が表示されます。

私はJUnit Testingの基本的な構文についていくつかのアイデアを持っています
。ユニットテストは初めてなので、それだけしか知りません。

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 ではクラス) を他のクラスの干渉なしにテストすることを意味します。もちろん、アプリケーションには複数のクラスがあり、それらは相互に使用されます。しかし、モック オブジェクトを使用すると、クラスが必要とする必要なものを提供するだけで、テスト対象のクラスが実行時に使用するクラスのオブジェクトではない、テスト対象のクラス オブジェクトを指定できます。モック オブジェクトは、実際のオブジェクトのように見えます。どのメソッド呼び出しでどの値を返すかを正確に指定します。

そうすれば、他のクラスが干渉することなく、単一のクラスをテストできます。これにより、問題を簡単に検出できます (考えられる原因は 1 つだけです)。通常、クラスごとに 1 つの単体テスト ケースを記述します。

これはクラスごとのソリューションであるため、基本的にどのフレームワークを使用するかは重要ではありません。ただし、一部のフレームワークはテストをサポートします (完全に単体テストされ、依存関係の挿入をサポートします) が、他のフレームワークはサポートしません (たとえば、多くのシングルトン)。

指定されたクラスをテストするにはどうすればよいですか?

単一のクラスに対してのみ、JUnit テスト ケースを適切に記述します (優れた IDE がそれをサポートします)。このクラスがあなたのコードではない別のクラスを拡張する場合、オブジェクトのみを親として持つクラスのテストを書くのと同じくらい簡単です。親のメソッドをテストする必要はありません。自分のメソッドだけをテストしてください。理想的には、コンストラクターには副作用がありません。オブジェクトを安定状態に初期化するだけで、他のアクションを開始しません。そうすれば、独自のコードベース内でクラスを拡張するクラスを単体テストすることもできます。親クラスはコンストラクター (およびおそらくクラス内のいくつかのメソッド呼び出し) にのみ使用されるため、サブクラスのメソッドのテストに集中できます。

すべてのクラスの単体テストを作成するように、親クラスの単体テストも作成します。問題が親クラスにある場合、関連するテスト ケースがそれを見つけます (適切に記述されていれば)。

あなたの質問に戻ります: まず、MVC をテストすることは何もありません。MVCはデザインパターンです。ユニット テストの 2 番目に、クラスの相互作用をテストしません (機能テストを探します)。

機能テスト

機能テストは、コンポーネントの特定のサブセットの相互作用をテストします。1 つの機能テストでは、CMS でのログインをテストできます。1 回のログインには、多数のクラスが必要です。テスト タイムラインでは、最初に単体テストを実行し、次に機能テストを実行します (これらにはワーキング クラスが必要なため)。何かがうまくいかないときはいつでも、問題を修正した後に手順を再実行する必要があります。

概要

「MVC」をテストするためのサンプルを要求しました。前に説明したように、MVC はパターンであるため、MVC をテストすることほど重要なことはありません。示されているサーブレットには 1 つの巨大なメソッド (それがどれほど適切に構造化されているかについてのコメントはありません) と、それを呼び出すだけの 1 つのメソッドがあるため、あまりテストしやすいビルドではありません。さらに、メソッドは保護されているため、ブラックボックス テストではなくホワイト ボックス テストを行う必要があります。

機能テストは、実際に複数のクラスを使用してそれらの相互作用をテストできるため、興味深い場合があります。たとえば、クラスが XYZ を実行してクラス B の設定を変更する場合、クラスのメソッドを呼び出して相互作用をテストし、期待される結果をクラス B の実際の設定と比較できます。

与えられたコードだけでは、動作するテスト サンプルは実際には実用的ではありません。

于 2013-07-29T16:34:35.623 に答える