AOP@Work: 对方面进行单元测试

发表于:2008-2-01 17:33

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:网络转载

优缺点

  这项技术实际上是对上一项技术的优化。通过只显示改变,横切比较工具可以帮助防止信息盲点。同时,cross-references 视图要求选择需要分析的建议或者类,而横切比较工具使您可以检查整个项目的改变。

  缺点是横切比较工具在方面影响多个联结点时会不好用。考虑一个记录所有公共方法的日志。这样一个方面在哪怕一天的开发后也会增加十来个新改变,使得查看其他更重要的改变变得困难了。在真实世界中,横切比较工具可以有很多配置,对某些方面的改变发出警报,而忽略与其他方面有关的改变。

III. 使用委派

  方面可以并且通常用普通对象实现横切行为。可以利用这种关注点的分离分别测试横切规范及它们的行为。下面两个模式展示如何使用委派和 mock 对象检查方面的这两个部分。

模式 1. 测试委派的建议逻辑

针对 :横切功能

概述 :如果还没有做的话,可以将一些或者全部建议逻辑委派给其他可以直接测试的类。(如果愿意的话,还可以将行为委派给方面的公共方法。)

例子:将突出显示逻辑转移到其他类

  要更好地在隔离状态下测试突出显示逻辑,可以将它转移到一个专门的工具类中:

  private HighlightUtil highlightUtil = new CssHighlightUtil();
 
  public void setHighlightUtil(HighlightUtil highlightUtil){
  this.highlightUtil = highlightUtil;
  }
 
  String around(Highlightable highlightable) :
      highlightedTextProperties() && this(highlightable)
  {
    String result = proceed(highlightable);
    return highlightUtil.highlight(result, highlightable.getHighlightedWords());
  }
    


  通过抽取突出显示逻辑,可以编写调用 HighlightUtil 类的方法的单元测试。

优缺点

  这项技术使得在域逻辑中产生边缘用例更容易了。它还有助于隔离问题,如果 helper 类的测试失败,就会知道是它而不是方面有问题。最后,委派逻辑通常会得到更干净的关注点分离。在这个例子中,通过将文字突出显示逻辑抽取到其它类,它变成系统其他部分可以独立于这个方面使用的一项操作。从而使方面获得了使用不同的突出显示策略的灵活性(HTML 的 CSS 突出显示、纯文本的全部大写突出显示等等)。

  不利的一面是,这种技术在逻辑难于抽取时就无能为力了。例如,最好让简单的逻辑留在原处。同时,一些方面将状态存储到本地或者它们建议的类的 ITD 中。状态存储通常构成了方面逻辑的签名部分,它并不总能干净地转移到 helper 类中。

模式 2. 使用模拟对象记录建议触发

针对 :横切规范和功能

  概述 :这项技术补充了前一项技术。如果将建议行为抽取到另一个类中,那么就可以用一个 mock 对象替代 helper 类对象,并验证建议是否在正确的联结点上触发。还可以验证建议将正确的上下文传递给了 helper 类,不管是直接用建议参数还是用之前存储的状态。

注: 如果需要对 mock 对象的介绍,请参阅 参考资料。

例子:用一个 mock HighlightUtil 测试 Highlighter 方面

  我们已经看到了方面如何委派到另一个类中以处理实际的文字突出显示。这使得在测试中向方面注入不同的 highlighter 实现成为可能。清单 3 中的代码利用 JMock 库做到了这一点。(请参阅 参考资料。)


清单 3. 用 JMock 测试来自方面的调用

public class DelegatedHighlightingUnitTest extends MockObjectTestCase {
  Collection<String> words;
  private HighlightUtil original;
  private SearchResult result;
  private Mock mockUtil;
  public void setUp() throws Exception {
    super.setUp();
    setUpMockHighlightUtil();
    words = Collections.singleton("big");
    result = new SearchResult();
    result.setTitle("I am a big bear!");
    result.setHighlightedWords(words);
  }
  private void setUpMockHighlightUtil() {
    original = HighlightResults.aspectOf().getHighlightUtil();
    mockUtil = mock(HighlightUtil.class);
    HighlightResults.aspectOf().setHighlightUtil((HighlightUtil)mockUtil.proxy());
  }
  public void testHighlightUtilAppliedToTitleOfSearchResult() {
    mockUtil.expects(once())
      .method("highlight")
      .with(eq("I am a big bear!"), eq(words));
    result.getTitle();
  }
}
 


  setUp() 方法实例化 mock 对象并将它注入到方面中。测试方法告诉 mock 等待对名为 “highlight” 的方法的调用,这个方法有两个参数:getTitle() 的返回值和在 SearchResult 中存储的单词清单。设置了期望后,测试调用 getTitle() 方法,它应当触发方面并产生预期的对 mock 的调用。如果 mock 没有收到调用,那么它就会在销毁时自动使测试失败。

  注意 setUp() 方法存储了到原来 HighlightUtil 的引用。这是因为方面像大多数对象一样,是单元素(singleton)的。因此,销毁时撤销 mock 注入的影响很重要,否则,mock 会持续留在方面中并影响其他测试。这个方面的正确销毁如下所示:

  @Override
  protected void tearDown() throws Exception {
    try {
      HighlightResults.aspectOf().setHighlightUtil(original);
    } finally {
      super.tearDown();
    }
  }
 


优缺点

  这个模式对前一个模式做了补充,只是它测试方面的横切规范和上下文处理而不是横切行为。因为不用检查方面的输出的间接副作用,所以可以更容易地产生联结点匹配和上下文传递行为中的临界用例。

  重要的是要认识到委派逻辑的优缺点,用 mock 进行测试对于使用对象或方面的技术都是类似的。在这两种情况下,都是分离关注点,然后以更隔离的方法验证每一个关注点。

  对于注入 mock 来说,有一个特定于方面的问题。如果使用单元素方面(默认的),那么对于方面的字段所做的所有改变,如用 mock 替换一个字段,在测试结束时都必须撤销。(否则,mock 会挂起并可能影响系统的其他部分。)这种销毁逻辑很难实现和记忆。编写一个测试清理方面,自动在每次测试后像在例子中那样重新设置方面从概念上来说是简单的,但是其细节超出了本文的范围。

54/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号