【轉(zhuǎn)帖】jMock Argument Interceptor - 一種獨(dú)特的設(shè)計(jì)思路

          jMock Argument Interceptor - 一種獨(dú)特的設(shè)計(jì)思路
          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 閱讀(252) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): unit testing


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(2)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          收藏夾

          db2

          dos

          Groovy

          Hibernate

          java

          WAS

          web application

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 北流市| 高青县| 巴林左旗| 应城市| 台北县| 西青区| 淮滨县| 枣强县| 吴桥县| 格尔木市| 文水县| 根河市| 壤塘县| 儋州市| 银川市| 万年县| 高淳县| 清徐县| 巴楚县| 衢州市| 万荣县| 陆川县| 布尔津县| 泰安市| 三河市| 北宁市| 濮阳市| 板桥市| 丰宁| 黄骅市| 乐亭县| 衢州市| 锡林郭勒盟| 玉门市| 富川| 关岭| 大方县| 金川县| 资兴市| 青州市| 承德市|