在Robolectric测试中注入模拟对象

4

我需要为一个具有私有字段(即 presenter)的特定 Activity 构建 Robolectric 测试。为了将 mock 对象注入该字段,我使用了反射,因为我所在的项目没有依赖注入框架。

我的测试设置如下:

MyActivityTest.java

public class ConsumoViewTest {

@Mock
MvpConsumo.Presenter mockPresenter;

private MyActivity view;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
    ActivityController<MyActivity> activityController =
        Robolectric.buildActivity(MyActivity.class);
    view = activityController.get();
    try {
        FieldUtils.writeField(view, "presenter", mockPresenter, true);
    } catch (IllegalAccessException e){
        //Exception handling
    }
    activityController.setup();
}

作为我的Activity设置的一部分,它创建并添加了一个Fragment,在OnAttach()期间,Fragment调用了presenter的getter。现在,我无法理解的是,Activity返回一个真正的presenter,而不是我注入的mock presenter。这个真正的presenter最终调用了我的真实模型和真实webservice,这显然并不理想用于测试。
有人知道为什么在这种情况下忽略了我的mock吗?

很棒你找到了答案。为什么要使用反射来注入Presenter? - Eugen Martynov
由于项目限制,我无法包含Dagger2或其他DI框架。使用反射测试私有字段是不好的,但我认为仅为测试创建一个setPresenter方法也不会更好。 - Nicolás Carrasco-Stevenson
不需要 DI 框架。当您无法控制生命周期时,这种方法会带来问题,您并不总是能够在测试期间的 when 之前停止进程以注入依赖项。 - Eugen Martynov
我正在使用Roboelectric进行测试,因此在测试期间我可以控制Activity的生命周期。话虽如此,我很好奇您认为在这里注入presenter的更好方法是什么。 - Nicolás Carrasco-Stevenson
我的意思是,您仍然无法拆分onCreate()或任何其他正在测试的类的方法。因此,如果您需要精确控制注入内容的位置,则您的方法将无法正常工作。 - Eugen Martynov
1个回答

2
在写完问题后,我意识到问题所在。我的反射确实起作用了,演示者被初始化为Mock,但是我忘记了在Activity.OnCreate()期间将演示者初始化为真正的演示者,从而覆盖了之前注入的Mock。

我遇到了同样的问题,我的Presenter在Activity创建时初始化,并且Presenter在数据库中查找数据,因此我的测试无法工作,有什么办法可以模拟我的Presenter吗? - Umesh Chakradhar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接