ron*_*tho 5 java android unit-testing robolectric dagger
我正在使用Dagger进行依赖注入,它在我的应用程序中运行良好但我无法测试它.为了创建模块依赖图,我遵循了这种模式:https://github.com/pyricau/shipfaster/blob/master/src/main/java/com/squareup/shipfaster/common/ShipFasterApplication.java
现在,在我的MainActivity测试类中,我希望能够在调用Activity onResume()方法时验证与mock的交互.
这是班级:
@Config(emulateSdk = 18)
@RunWith(RobolectricDaggerTestRunner.class)
public class MainActivityTest extends TestCase {
@Inject MainActivity sut;
public @Mock MyObject mockMyObject;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
ObjectGraph.create(new TestModule()).inject(this);
}
@Test
public void testThatMyActivityDelegatesDoSomethingToMyObject(){
//init
ActivityController<MainActivity> activityController = ActivityController.of(sut);
//run
activityController.create().start().resume();
//verify
Mockito.verify(mockMyObject).doSomething();
}
@Module(
includes = {ActivityModule.class},
injects = MainActivityTest.class,
overrides = true,
library = true
)
class TestModule {
@Provides
MyObject provideMyObject() {
return mockMyObject;
}
}
}
Run Code Online (Sandbox Code Playgroud)
从我所看到的,该onCreate()方法被调用,但使用的是真实的实例myObject,而不是被模拟的实例.测试失败了"想要但未被调用 - 实际上,与这个模拟没有交互." 错误.
也许这是因为我尝试使用Robolectric创建的MainActivity与我的TestModule没有关联,因为它是在Application级别创建的,但是我设法通过在MainActivity上显式调用方法并放置myObject来使该测试通过. doSomething()在那里,但我需要的是测试Android生命周期调用.
关于如何设法测试这个的任何想法?
使用真实对象是因为我猜你ObjectGraph在Application类中进行了初始化。当您在((Application) getApplication()).inject(this)测试期间调用时,您使用的方法ObjectGraph与刚刚运行应用程序时的方法相同。
ObjectGraph在此测试中,您将使用 的模拟实例创建全新的MyObject。这个模拟仅被注入MainActivityTest,因为当MainActivity inject()调用 in 时,它使用ObjectGraphmade in Application。
您可以做的是创建TestApplication类(它必须与您的类具有相同的包Application,但需要位于测试目录中),它扩展您的应用程序,并添加您TestModule以使用模拟覆盖真实实例。例如这样:
package com.example.myapp;
public class MyApplication extends Application {
ObjectGraph graph;
private Account currentAccount;
@Override
public void onCreate() {
super.onCreate();
graph = ObjectGraph.create(getModules().toArray());
init();
}
void init() {
// initialization stuff should not be called in tests
}
List<Object> getModules() {
List<Object> modules = new ArrayList<>();
modules.add(new ActivityModule(this));
return modules;
}
public void inject(Object object) {
graph.inject(object);
}
}
Run Code Online (Sandbox Code Playgroud)
package com.example.myapp;
public class TestMyApplication extends MyApplication {
@Override
void init() {
}
@Override
List<Object> getModules() {
modules = super.getModules();
modules.add(new TestModule());
return modules;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1073 次 |
| 最近记录: |