如何从嵌套包中测试代码

时间:2014-11-23 15:32:49

标签: java android junit mockito android-testing

我想用mockito测试我的java代码,而 NOT 喜欢让我的所有方法都公开。

我的问题如下,我们假设我有以下代码:

package com.whatever;

public class Parent
{
    public void PlayWithChild(Child child)
    {
        child.Hug();
    }
}

package com.whatever.subpackage;

public class Child
{
    public void Hug()
    {
    }
}

我有测试:

package com.whatever;

import com.whatever.subpackage;

public class Test
{
    @Test
    public void PlayWithChild_ChildHugged()
    {
        //Arrange
        Child mckChild = Mockito.mock(Child.class);

        //Act
        new Parent(mckChild).PlayWithChild();

        //Assert
        Mockito.verify(mckChild).Hug();
    }
}

现在,如果我让Hug方法包可以访问(删除)' public',那么我无法从测试中访问它...而且我不想放置所有内容(Parent) ,CHild和我的整个可测试库)到同一个包,我想组织它们。

1 个答案:

答案 0 :(得分:1)

您需要确定您希望设计具有的封装和抽象程度。 Java没有特别精细的方法来指定哪些组件可以从哪些其他组件访问,因此您可能必须在文档中表达这些组件,而不是依赖编译器为您强制执行它们。

在你的情况下,我认为你应该公开Hug方法;如果你想让它变得非常清楚,可以添加相应的Javadoc或将Child放入名为" internal"的子包中。阻止其随意使用。


Java的四个访问级别:

  • public访问权限,对测试或模拟没有任何问题
  • protected访问权限,包括包访问和包外子类。在同一个包中进行测试很简单,但您可能需要创建手动测试双精度来访问/验证相关包外部的受保护方法调用。
  • 默认或包私有访问,如您所述,可以在同一个包中轻松测试/调用。从其他包中,这些方法不会以任何有意义的方式存在于调用或测试中。
  • private方法,无法直接调用或测试。

为什么有人会在测试驱动的开发中创建私有方法?简单:因为私有方法是一个不需要测试的实现细节。同样,protected或包私有方法是不需要在包外进行测试的实现细节。在这里,如果Hug()方法是公共的并且它调用私有或包私有方法FeelBetter(),那么来自其他包的调用者应该只通过 public API Hug而不调用或关注自己的实现详情如FeelBetter()。

这样做的结果是几乎鼓励大型,过度使用的包,因为这可能是隐藏其他包中不相关的实现细节并限制入口点数量的最佳方式。将密切合作者放在同一个软件包中允许小包API ,这是一个很好的目标。但是,如果一个包中有足够的类,这个概念就会崩溃;幸运的是,它只会在包被证明是这么大时才会崩溃,它需要两个独立的包,此时你可以停下来思考哪些组件是连接的,哪些组件可以提取到API中他们自己的。这可能意味着扩展某些类/方法从包到公共的访问,这在拆分包时是可以预期的。它还可能意味着为了测试而添加可访问的getter或其他状态查询方法,这在开发可测试组件时也是可以预期的。

有关如何制作可测试系统以及如何与测试双打(或实际测试的组件)进行交互的更多信息,我建议阅读Martin Fowler的文章 Mocks Aren't Stubs