我创建了一个扩展第三方抽象类的新类。新类调用抽象类中的方法。我遇到的问题是在尝试编写单元测试时,我不确定如何编写测试,因为我不知道第三方类需要的确切细节。
下面的AbstractDecoratorMapper是一个SiteMesh特定类,我必须扩展它以使SiteMesh正常工作。据我所知,从文档中我不能使用合成。
public final class PartnerDecoratorMapper extends AbstractDecoratorMapper {
@Override
public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException {
super.init(config, properties, parent);
}
@Override
public Decorator getDecorator(HttpServletRequest request, Page page) {
if (super.getDecorator(request, page).getName().equalsIgnoreCase("default")) {
return getNamedDecorator(request, "externalPartnerDefault");
}
return super.getDecorator(request, page);
}
}
如果此工具可以提供任何帮助,我会使用JMock。
答案 0 :(得分:4)
你不需要知道来自第三方库的细节......你只需要模仿他们返回你期望的东西。
如果你继承它,你可以设置类,因为它将在生产中使用,并调用应该在常规使用中调用的方法。您需要检查的是结果是否符合您的预期。 (您无需确切知道第三方类如何在测试中工作)。
为了检查您实施的所有代码是否已执行,您可以使用插件检查覆盖范围,例如eclemma - http://www.eclemma.org/)
答案 1 :(得分:3)
使用JMock,你不能尽我所知模拟对被测试类的超类的调用。
this related question的答案可能有用,但主要答案是切换到支持此功能的模拟框架(JMockit)。
答案 2 :(得分:1)
您可能会问两件事。我会尝试回答这两个问题。
可能的问题1)如何测试我的附加功能?
可能的问题2)如何测试组合功能是否合适?
让我先从问题1开始。
我建议简单的剥皮。这里有一个技术视频:http://www.youtube.com/watch?v=p0tILwRZH5Q (视频是c#但在java中基本相同)
这意味着之后您将拥有以下代码
@Override
public Decorator getDecorator(HttpServletRequest request, Page page) {
Decorator d = super.getDecorator(request, page);
return getResolvedDecorator(d, d.getName(), request);
}
public Decorator getResolvedDecorator(Decorator current, String name, HttpServletRequest request) {
if (name.equalsIgnoreCase("default")) {
return getNamedDecorator(request, "externalPartnerDefault");
}
return current;
}
现在你可以通过像
之类的调用来测试它assertEquals(expected, new PartnerDecoratorMapper().getResolvedDecorator(null, "default", MockHttpServletRequest);
我建议也可以从HttpServletRequest中删除数据,以进行测试和测试。意图更清晰。
注意:这具有额外的性能优势,即对super.getDecorator()的调用只发生一次,因为结果是缓存的。
附加说明:值得注意的是,init()的覆盖是不必要的,实际上并没有做任何事情。
问题2:这是一个更难的问题,因为您没有说明所需的行为是什么。 我假设这是一个工厂模式,所以很可能它会以某种方式工作,如
| http请求质量1 |页面质量1 |期待装饰者| | / mypath / mypage | status = foo | MyDecorator |
(我不知道上面的图表应包含或看起来像什么) 一旦你有这种行为,那么测试将确保它是相当直接的。
快乐测试, 卢埃林
答案 3 :(得分:1)
因为我不知道第三方课要求的具体细节
任何类型的测试都会比较实际所做的事情与应该要做的事情。在你知道应该做什么之前你不能测试:“第三部分课程需要什么”。
如果您不知道基类需要什么,那么如何合理地尝试编写派生类?您要扩展的课程的API文档是什么?
问题可能是没有这样的API文档,或者它没有信息吗?可能是,虽然该类不是final
,但它实际上并不打算用作基类。其中任何一个都表明设计不佳的API,并建议您不要打扰使用它
或者您不知道确切详细信息的关键难点?这可能是您的方法中的一个缺陷:通常您不能也不能对完全详细信息做出假设。您的代码应该符合文档化的API,并且您不应该假设任何未在文档化的API中声明的内容。这可能意味着您无法知道何时可以调用模板方法或将值传递给它们。如果基类通过传递声明为实现interface
或非final
类的对象(即,它们的类型而不是它们的<)来与模板方法进行通信指定了em> class ,你无法知道这些对象将具有哪个类。