如何测试使用Lookups的NetBeans平台代码?

时间:2015-10-21 14:20:05

标签: java unit-testing netbeans-platform

TL; DR如何使用静态方法查找依赖项的NetBeans平台代码编写单元测试?

在NetBeans平台应用程序中,我遇到了这样的代码:

MyService service = Lookup.getDefault().lookup(MyService.class);
service.doStuff(....);

对我来说,静态访问看起来像反模式,很难测试。当我在Google周围时,我只能找到关于低耦合和高内聚,远程接口等的评论。

很多人似乎think this is a Good Idea但我想知道如何为这样的代码编写合理的单元测试,而不需要在单元测试中使用模拟静态方法或使用Lookup功能。

我想到的第一个想法是将查找重构为常规依赖:

public class MyClass {

   private Lookup lookup = Lookup.getDefault();

   public void myMethod() {
       MyService service = lookup.lookup(MyService .class);
       service.doStuff(....);
   }

   public void setLookup(Lookup lookup) {
       this.lookup = lookup;
   }

然后使用setter提供模拟Lookup进行测试。

这可以工作,但仍会导致测试代码在设置模拟之前调用Lookup.getDefault()。 Netbeans平台没有提供常规的依赖注入机制,所以如果我这样介绍它就会感觉就像在游戏中游泳一样。

我觉得我错过了什么。是否有标准方法为Netbeans平台代码编写单元测试?

2 个答案:

答案 0 :(得分:3)

到目前为止,我找到了解决这个问题的几种方法。

1 - 在具有更高位置的Lookup中发布该类的测试版本

@org.openide.util.lookup.ServiceProvider(service = MyService.class, position = 1)
public class TestService implements MyService {
    public void doStuff(....) {

2 - 使用NBJunit的MockService

public class MyTest extends NbTestCase {
    public void setUp() throws Exception {     
        org.netbeans.junit.MockServices.setServices(TestService.class);
    }

3-注册您自己的查找实现:

static {
    System.setProperty("org.openide.util.Lookup", TestLookup.class.getName());
}

public class TestLookup extends org.openide.util.lookup.AbstractLookup {
    public TestLookup() {
        this(new org.openide.util.lookup.InstanceContent());
    }

    private TestLookup(org.openide.util.lookup.InstanceContent ic) { 
        super(ic);
        ic.add(new TestService());
    }

其中一些想法可以在这里找到:https://openide.netbeans.org/tutorial/test-patterns.html

答案 1 :(得分:0)

类TestService必须在您的测试类中可见(通常,我们使用Lookup来消除依赖性,这就是接口和实现在单独模块中的原因)。

考虑在测试模块的独立性中添加TestService模块。