繁体   English   中英

如何测试调用私有方法的匿名内部类

[英]How to test an anonymous inner class that calls a private method

我们有一堆类从服务器侦听事件然后响应它们。 例如:

class EventManager {
    private Set<Event> cache = new HashSet<Event>();

    private EventListener eventListener = new EventListener() {
        void onEvent(Event e) {
          if (e instanceof MyEvent || e instanceof YourEvent) {
            handleEvent(e);
          }  
        }
    }

    public EventManager(ServerCommunication serverComm) {
        serverComm.addListener(eventListener);
    }

    private handleEvent(Event e) {
        // handle the event...
        // ...
        cache.add(cache);
        // ...
    }
}

这是我们正在做的事情的一个组成例子。 以下是我看到的问题:

  1. 我想测试handleEvent以确保它正在做它应该做的事情,但我不能,因为它是私有的。
  2. 我还想检查一下是否有东西被添加到缓存中,但这似乎也很困难,因为缓存是私有成员,我不想添加一个不必要的getter方法。
  3. 我还想测试匿名类的onEvent方法中的代码。

现在,我所做的是将所有逻辑从匿名类移到handleEvent方法,并使handleEvent包为private(我的单元测试在同一个包中)。 我不是在检查缓存的内容,尽管我想。

有没有人对更可测试的更好的设计有任何建议?

我可能会提取一个EventCache组件。 您可以使用实现计算缓存事件或记录任何感兴趣的内容来替换此测试。

我可能不会改变handleEvent的可见性。 您可以实现一个ServerCommunication,它只是从测试用例中引发事件。

嗯,这里有两种方法:黑盒子和白盒子。

黑盒测试表明您应该只测试公开可见的更改。 这种方法是否有任何可观察到的影响? (有些事情没有 - 缓存是一个明显的例子,它们可以提高性能,但可能会看不见。)如果是这样,请测试一下。 如果没有,测试它没有负面影响 - 这可能只是加强其他测试的情况。

白盒测试表明,为了测试,你可以添加一个包级方法,例如

Cache getCacheForTesting()

通过在名称中加入“for testing”,您可以明白每个人都不应该从生产代码中调用它。 您可以使用注释来指示相同的内容,甚至可能有一些构建规则,以确保生产中的任何内容都不会调用此类方法。

这最终变得更加脆弱 - 与实现更紧密相关 - 但它确实使得更容易彻底地测试代码,IMO。 就我个人而言,我在单机测试的白盒测试方面犯了错误,而集成测试肯定是更黑盒子。 其他人对于测试公共API更加教条。

我假设你的EventManager是一个单例,或者你可以访问你正在测试的类的特定实例。

1 - 我想你可以向你的班级发送活动。 你的方法是私有的,没有其他人可以调用它,然后发送一个事件就足够了。

2 - 如果你真的需要,可以通过反射访问它。 您的测试将取决于特定的实现。

3 - 实际上你想测试什么? 如果要确保调用此方法,可以通过反射将EventListener替换为另一个EventListener对象(并最终从新侦听器调用第一个侦听器的onEvent方法)。 但是你的问题似乎更多是关于代码覆盖而不是实际的单元测试。

有时候,当遇到我想要测试的私有方法时......他们只是尖叫为另一个对象上的公共方法。

如果您认为HandleEvent值得单独测试(而不是通过onEvent处理),一种方法是将HandleEvent作为新/不同对象的公共方法公开。

利用这个机会将代码分解为更小的更集中(默认访问)类。 测试只是代码的另一个客户端。

请注意,匿名内部类' onEvent方法实际上是可访问的,因此调用它应该不是问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM