java-用所述类的抽象版本模拟通用类

我正在尝试模拟一个抽象类,但是从我所看到的来看,我认为这是不可能的.我们有一些使用泛型的类,它们必须扩展特定的抽象类.他们中有一整群人,他们已被成功嘲笑.抽象类有一个处理返回泛型的方法,如下所示:

public abstract class ChildPresenter <T extends ChildView> {
    private T view;

    public abstract T getView();
}

我们正在测试的类包含以下内容:

public class ParentPresenter {
    private ConcreteChildPresenter1 childPresenter1;
    private ConcreteChildPresenter2 childPresenter2;
    private ConcreteChildPresenter3 childPresenter3;
    private ConcreteChildPresenter4 childPresenter4;
    List<ChildPresenter> childPresenters;
}

在构造函数中,这些类使用Google Guice注入,设置为变量,并添加到子演示者列表中.

被测试的方法是一种迭代所有childPresenters对象并运行方法getView()的方法.

我在测试课程中尝试了这种方式:

public class ParentPresenterTest {
    private ConcreteChildPresenter1 childPresenter1;
    private ConcreteChildPresenter2 childPresenter2;
    private ConcreteChildPresenter3 childPresenter3;
    private ConcreteChildPresenter4 childPresenter4;
    private List<ChildPresenter> childPresenters;

    //This is an abstract class 
    private ChildView childView;

    @BeforeTest
    public void createInjector() {
        Guice.createInjector(...//Creates a fake module and does binding for the variables mentioned earlier
            //e.g.
            childPresenter1 = mock(ConcreteChildPresenter1.class);
            binder.bind(ConcreteChildPresenter1.class).toInstance(childPresenter1);
            //e.t.c for other variables

            //Same for child view
            childView = mock(ChildView.class);
            binder.bind(ChildView.class).toInstance(childView);
        }

        childPresenters = new ArrayList<ChildPresenter>();
        childPresenters.add(childPresenter1);
        //Add all child presenters

        for(ChildPresenter childPresenter : childPresenters) {
            when(childPresenter.getView()).thenReturn(childView);
        }
    }
}

问题发生在when(childPresenter.getView()).thenReturn(childView);由于Mockito抱怨​​以下消息:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue:

ChildView$$EnhancerByMockitoWithCGLIB$$2f6a4bd5

cannot be returned by getView() getView() should return ConcreteChildView1

*** If you’re unsure why you’re getting above error read on. Due to the nature of the syntax above problem might occur because:

  1. This exception might occur in wrongly written multi-threaded tests. Please refer to Mockito FAQ on limitations of concurrency testing.

  2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.

我能理解,但是当我想做的是使用以下方法确认模拟的ChildView称为单个方法时,模拟每个具体的ChildView似乎很浪费:

verify(childView, atLeast(childPresenters.size())).getView();

还有另一种方法吗?我可以以某种方式使用模拟的抽象类代替具体的抽象类吗?

编辑这是如何实现getView()方法的具体版本:

public ConcreteChildPresenter1<ConreteChildView1> {

    @Override
    public ConreteChildView1 getView() {
        view.buildView();
        return view;
    }
}

还有所有子视图扩展的抽象ChildView类:

public abstract ChildView {

    public abstract void buildView();
}

解决方法:

由于每个子提示者都返回特定类型的视图,因此,正如您已经了解的那样,您不能用抽象类ChildView的模拟代替它们.

只有在您提供正确的实现(如此处所述)的情况下,才有一种在运行时获取ChildView具体类型的方法:Get generic type of class at runtime

然后,您可以通过以下方式初始化演示者的模拟:

for(ChildPresenter childPresenter : childPresenters) {
    //this getter returns the needed runtime class
    when(childPresenter.getView()).thenReturn(mock(childPresenter.getViewType())); 
}
上一篇:java-Junit Mockito没有按预期嘲笑


下一篇:Android AsyncTask和Mockito(或PowreMockito)