【问题标题】:Mockito calling real methods when attempting to stub methods implemented on a package private superclassMockito 在尝试对包私有超类上实现的方法进行存根时调用真实方法
【发布时间】:2015-08-18 08:31:09
【问题描述】:

这可能是与this question 相同的根本问题,但更容易重现。

问题是在模拟的公共类上存根接口方法时,该类扩展了具有接口方法实现的包私有类。 Mockito 会在包私有类中调用真正的接口方法实现。请参阅以下示例。

界面

public interface DontCallMe {
    int dontCallMeSuper();
    int dontCallMe();
}

实现接口方法之一的包默认类。

abstract class PackagePrivate
        implements DontCallMe {

    @Override
    public int dontCallMeSuper() {
        throw new IllegalArgumentException("don't call me super");
    }
}

实现另一个的包私有类的公共子类。

public class Public
    extends PackagePrivate {

    public Public() {
        super();
    }

    @Override
    public int dontCallMe() {
        throw new IllegalArgumentException("don't call me");
    }
}

测试类

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.Test;

public class ExampleJunit {

    @Test
    public void testStaticConstructorInnerClass() {
        final Public comparable = mock(Public.class);
        when(comparable.dontCallMe()).thenReturn(1);
        when(comparable.dontCallMeSuper()).thenReturn(1);
    }
}

运行测试的结果

java.lang.IllegalArgumentException: don't call me super
at PackagePrivate.dontCallMeSuper(PackagePrivate.java:6)
at Public.dontCallMeSuper(Public.java:1)
at ExampleJunit.testStaticConstructorInnerClass(ExampleJunit.java:19)

我可以通过公开PackagePrivate 来解决这个问题,但这不是很好。我有什么办法可以存根在 PackagePrivate 类上实现的方法?

【问题讨论】:

    标签: java mockito


    【解决方案1】:

    您可以模拟接口 (DontCallMe) 而不是类 (Public):

        final DontCallMe comparable = mock(DontCallMe.class);
    

    或者,如果您需要模拟 Public 中但不在 DontCallMe 中的方法,您可以创建一个新接口并模拟它。

    例如,使用您原来的 DontCallMe 定义,您可以这样做:

    public interface IPackagePrivate extends DontCallMe {
        int extraMethod();
    }
    
    ------
    
    abstract class PackagePrivate implements IPackagePrivate { 
        public int dontCallMeSuper() { 
            throw new IllegalArgumentException("don't call me super");
        } 
    }
    
    ------
    
    public class Public extends PackagePrivate { 
    
        public Public() { 
            super(); 
        } 
    
        public int dontCallMe() { 
            throw new IllegalArgumentException("don't call me");
        }
    
        public int extraMethod() { 
            throw new IllegalArgumentException("extra method");
        } 
    } 
    
    ------
    
    import static org.mockito.Mockito.mock; 
    import static org.mockito.Mockito.when; 
    import org.junit.Test; 
    
    public class ExampleJunit { 
    
        @Test
        public void testStaticConstructorInnerClass() { 
            final IPackagePrivate comparable = mock(IPackagePrivate.class);
            when(comparable.dontCallMe()).thenReturn(1);
            when(comparable.dontCallMeSuper()).thenReturn(1);
            when(comparable.extraMethod()).thenReturn(1);
        } 
    } 
    

    【讨论】:

    • 没错,不幸的是,我正在模拟的实际代码比示例复杂得多,我无法模拟界面。
    • 我在答案中添加了更多内容。
    【解决方案2】:

    再做一些谷歌搜索,这是一个已知的 mockito 错误。见https://github.com/mockito/mockito/issues/168https://github.com/mockito/mockito/pull/171 中针对 mockito 2.0 提出的修复

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多