【轉帖】jMock Argument Interceptor - 一種獨特的設計思路

          jMock Argument Interceptor - 一種獨特的設計思路
          Motivation
          An Object you need to test is constructing another complex object internally which you cannot access and this object is passed to a collaborator you can replace with a mock.
          Solution
          Write an Interceptor (a custom jMock Stub ) to intercept the argument passed to the mocked method. The Interceptor exposes the argument, allowing for standard jUnit assertions.
          Alternatives

              * Use a custom jMock Constraint when the argument's asserted state is simple.
              * Use a Fake Object when a class cannot be dynamically mocked.

          Example

          public void testInterceptArgument() {

              List arguments = new ArrayList();

              Mock mockSubmissionTracker = mock(SubmissionTracker.class);
              mockSubmissionTracker.expects(once()).method("record").will(captureArgumentsIn(arguments));

              SecretLottery lotto = new SecretLottery( (SubmissionTracker)mockSubmissionTracker.proxy());

              lotto.createTicket();

              LotteryTicket ticket = (LotteryTicket) arguments.get(0);
              assertEquals("Secret Number", 12345, ticket.number);
          }

          private Stub captureArgumentsIn(List argumentList) {

              return new ArgumentInterceptor(argumentList);

          }

          class ArgumentInterceptor implements Stub {

              List arguments;

              public ArgumentInterceptor(List argumentList) {
                  arguments = argumentList;
              }

              public Object invoke(Invocation invocation) throws Throwable {
                  arguments.addAll(invocation.parameterValues);
                  return null;
              }

              public StringBuffer describeTo(StringBuffer buffer) {
                  return buffer;
              }
          }

          The Traditional jMock approach
          The traditional way to handle this with jMock is to create a custom Constraint to verify the argument passed into the mocked method. Unfortunatly, this technique can produce a less explict test and a lot of supporting code. The above example handled with a traditional jMock Constraint would look like the following...

          public void testInterceptArgument() {

              Mock mockSubmissionTracker = mock(SubmissionTracker.class);
              mockSubmissionTracker.expects(once()).method("record").with(ticketNumber(12345));

              SecretLottery lotto = new SecretLottery( (SubmissionTracker) mockSubmissionTracker.proxy());

              lotto.createTicket();
          }

          private Constraint ticketNumber(final int ticketNumber) {

              return new Constraint() {

                  public boolean eval(Object arg) {

                      LotteryTicket ticket = (LotteryTicket) arg;  
                      return ticketNumber == ticket.number;
                  }

                  public StringBuffer describeTo(StringBuffer buffer) {
                      return buffer.append(ticketNumber);
                  }
              }
          }

          While this example works fairly well, each new test method would likely require its own Constraint. When the verification in the eval method becomes complex, it can become difficult to determine why a test is failing. An Argument Interceptor allows for traditional jUnit assertions, providing clearer failures for complex verfications.

          posted on 2011-01-31 22:24 koradji 閱讀(258) 評論(0)  編輯  收藏 所屬分類: unit testing


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導航

          統計

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          db2

          dos

          Groovy

          Hibernate

          java

          WAS

          web application

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 三明市| 那曲县| 辽中县| 禹城市| 夹江县| 射阳县| 莱西市| 合江县| 阜南县| 宝鸡市| 佛坪县| 横山县| 陵水| 稷山县| 彭泽县| 雷山县| 水富县| 西充县| 宁远县| 东海县| 宽城| 湄潭县| 昌乐县| 吴江市| 尉犁县| 博爱县| 宝应县| 富平县| 阿巴嘎旗| 绿春县| 山阴县| 井冈山市| 张家口市| 长兴县| 北川| 彩票| 合肥市| 奉化市| 古田县| 开封县| 定陶县|