重要的是要认识到委派逻辑的优缺点,用 mock 进行测试对于使用对象或方面的技术都是类似的。在这两种情况下,都是分离关注点,然后以更隔离的方法验证每一个关注点。
对于注入 mock 来说,有一个特定于方面的问题。如果使用单元素方面(默认的),那么对于方面的字段所做的所有改变,如用 mock 替换一个字段,在测试结束时都必须撤销。(否则,mock 会挂起并可能影响系统的其他部分。)这种销毁逻辑很难实现和记忆。编写一个测试清理方面,自动在每次测试后像在例子中那样重新设置方面从概念上来说是简单的,但是其细节超出了本文的范围。
IV. 使用 mock 目标
在最后一节中,我介绍了我自己发明的、用于描述在编写方面测试时用到的一种测试 helper 类类型的术语:mock 目标。在方面之前的世界中,一个 mock 对象 表示一个(手写或者动态生成)的类,它模仿要测试的一些类的协作器。与此类似,mock 目标 是一个模仿要测试的一些方面的合法建议目标的类。
为了创建 mock 目标,编写一个与生产中的建议有某些相似结构或者行为的类。例如,如果对于由 getter 返回的文字的突出显示感兴趣,可以编写下面这样的一个 mock 目标:
//an inner class of the enclosing test case
public class HighlightMockTarget implements Highlightable {
public String getSomeString() {
return "I am a big bear!";
}
}
然后,编写测试用例以验证方面正确地与目标交互,如清单 4 所示:
清单 4. 与 mock 目标交互以测试建议
public void setUp() throws Exception {
super.setUp();
setUpMockHighlightUtil();
words = Collections.singleton("big");
mockTarget = new HighlightMockTarget();
mockTarget.setHighlightedWords(words);
}
//mock setup/tearDown omitted
public void testHighlighting() {
mockUtil.expects(once())
.method("highlight")
.with(eq("I am a big bear!"), eq(words))
.will(returnValue("highlighted text"));
String shouldBeHighlighted = mockTarget.getSomeString();
assertEquals(shouldBeHighlighted, "highlighted text");
}
注意在这个例子中,我结合了 mock 目标和 mock 对象。mock 目标为下面三种技术提供了基础。
模式 1. 通过扩展一个抽象方面并提供一个切点来测试建议
针对 :横切功能
概述 :Prework :如果有必要,重新编写方面,将它分为一个抽象方面以及一个扩展它并具体化一个或者多个切点的具体方面。
有了抽象方面后,在测试类中创建一个 mock 目标。创建一个扩展了抽象方面的测试方面。让测试方面提供明确针对 mock 目标的切点。这个测试通过查找建议的已知副作用或者使用一个 mock 对象来验证方面中的建议是否成功。
示例:扩展 AbstractHighlighter
文章来源于领测软件测试网 https://www.ltesting.net/