我有一个严重依赖注入的 (dagger2) 应用程序.我想运行 espresso 测试,而无需让测试浏览整个应用程序,然后登录到应用程序.
I have a heavily dependency injected (dagger2) application. I would like to run an espresso test without having the test navigate through the whole application, and log into the application.
我想开始我的远程活动,并模拟登录管理器.然而,在任何@test 函数中,我们已经在调用onCreate 时命中了空指针.如果我在启动活动(如下所示)之前覆盖它,则活动为空.
I would like to start on my teleActivity, and mock the login manager. However in any @test function, we have already hit the null pointer as we have called onCreate. If I override it before we launch the activity (show below) the activity is null.
据我了解,切换下划线依赖项的能力是我们使用 Dagger2 的一个重要原因,否则它将只是一个过度设计的单例.如何覆盖、模拟或切换到测试匕首模块的注入 - 这样我就可以创建这个简单的 espresso 测试.
To my understanding, the ability to switch our underlining dependencies is a large reason why we use Dagger2, else it would be just a very over engineered singleton. How do I override, mock, or switch the injection to a testing dagger module -- so I can create this simple espresso test.
请注意,如果有影响的话,我也在 MVP 设计模式中编写了所有这些内容.
Note I also wrote all this in the MVP design pattern if that makes a difference.
远程活动
@Inject
TelePresenter mTelePresenter;
@Inject
public LoginStateManager mLoginStateManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
DaggerInjectorTele.get().inject(this);
mTelePresenter.setTeleDependencies(this);
Intent intent = getIntent();
String searchId = null;
if (intent != null) {
searchId = intent.getStringExtra(Constants.SEARCH_ID);
}
mTelePresenter.onCreateEvent(searchId,
Helper.makeAuthorizationHeader(
// CRASH Null pointer
mLoginStateManager.getBaseLoginResponse().getAccessToken()));
}
浓缩咖啡
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TeleTest {
@Rule
public ActivityTestRule<TeleActivity> mActivityTestRule = new ActivityTestRule(
TeleActivity.class) {
@Override
protected void beforeActivityLaunched() {
super.beforeActivityLaunched();
TeleActivity teleActivity = (TeleActivity)getActivity();
//teleActivity NULL!
teleActivity.mLoginStateManager = mock(LoginStateManager.class);
LoginResponse loginResponse = mock(LoginResponse.class);
when(loginResponse.getAccessToken()).thenReturn("1234");
// Nope here still null
when(teleActivity.mLoginStateManager.getBaseLoginResponse()).thenReturn(loginResponse);
}
};
匕首注射器
public class DaggerInjectorTele {
private static TelePresenterComponent telePresenterComponent =
DaggerTelePresenterComponent.builder().build();
public static TelePresenterComponent get() {
return telePresenterComponent;
}
}
TelePresenter组件
TelePresenterComponent
@Singleton
@Component(modules = {TelePresenterModule.class,
LoginStateManagerModule.class})
public interface TelePresenterComponent {
void inject(TeleActivity activity);
}
TelePresenter 模块
TelePresenterModule
@Module
public class TelePresenterModule {
@Provides
@Singleton
public TelePresenter getTelePresenter() {
return new TelePresenter();
}
}
LoginStateManager 模块
LoginStateManagerModule
@Module
public class LoginStateManagerModule {
@Provides
@Singleton
public LoginStateManager getLoginStateManager(){
return new LoginStateManager();
}
}
首先,您决定使用依赖注入 (Dagger2) 是一个非常好的决定,并且确实会让您的测试更容易编写.
First, your decision to use dependency injection (Dagger2) is a very good one and will indeed make your tests easier to write.
您必须覆盖依赖注入配置(模块)并注入一个模拟.下面是一个简单的例子来说明如何做到这一点.
You have to override dependency injection configuration (module) and inject a mock. Here is a simple example of how it can be done.
首先你需要一个模拟:
LoginStateManager lsmMock = mock(LoginStateManager.class);
现在覆盖 DI 配置以使用此模拟:
Now override the DI config to use this mock:
//Extend your TelePresenterModule, override provider method
public class TestTelePresenterModule extends TelePresenterModule{
@Override
public LoginStateManager getLoginStateManager() {
//simply return the mock here
return lsmMock;
}
}
现在开始测试:
@Test
//this is an espresso test
public void withAMock() {
//build a new Dagger2 component using the test override
TelePresenterComponent componentWithOverride = DaggerTelePresenterComponent.builder()
//mind the Test in the class name, see a class above
.telePresenterModule(new TestTelePresenterModule())
.build();
//now we initialize the dependency injector with this new config
DaggerInjectorTele.set(componentWithOverride);
mActivityRule.launchActivity(null);
//verify that injected mock was interacted with
verify(lsmMock).whatever();
}
示例来自:https://github.com/yuriykulikov/DIComparison/blob/master/app/src/androidTest/java/com/example/yuriy/dependencyinjectioncomparison/Dagger2Test.java
这篇关于Android 为 Espresso 测试模拟 Dagger2 注入依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
EditText:禁用文本选择处理程序单击事件上的粘贴EditText: Disable Paste/Replace menu pop-up on Text Selection Handler click event(EditText:禁用文本选择处理程序单击事件上的粘贴/替换菜
2.3 上带有完成 SoftInput 操作标签的多行 EditTextMultiline EditText with Done SoftInput Action Label on 2.3(2.3 上带有完成 SoftInput 操作标签的多行 EditText)
如何在 Android 中检测向左或向右滑动?How to detect the swipe left or Right in Android?(如何在 Android 中检测向左或向右滑动?)
防止在Android中的屏幕旋转对话框解除Prevent dialog dismissal on screen rotation in Android(防止在Android中的屏幕旋转对话框解除)
如何处理 ImeOptions 的完成按钮点击?How do I handle ImeOptions#39; done button click?(如何处理 ImeOptions 的完成按钮点击?)
您如何将 EditText 设置为仅接受 Android 中的数值How do you set EditText to only accept numeric values in Android?(您如何将 EditText 设置为仅接受 Android 中的数值?)