【轉帖】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

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 靖西县| 尼玛县| 涟源市| 金乡县| 噶尔县| 邓州市| 海盐县| 绍兴县| 宁陕县| 朔州市| 芒康县| 邢台市| 顺昌县| 阳山县| 额济纳旗| 溆浦县| 贡山| 土默特右旗| 彭水| 天气| 平谷区| 台江县| 宜宾市| 大新县| 拉萨市| 仙游县| 龙海市| 平利县| 都匀市| 法库县| 清苑县| 赞皇县| 长宁县| 乌鲁木齐县| 延寿县| 桂阳县| 长治市| 哈尔滨市| 瓮安县| 日土县| 澳门|