- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
android studio 3.4.1
dagger-android 2.21
我正在使用 dagger-android 将我的 OKHttpClient 注入(inject)到 espresso 规则中。但是还没有找到一种方法来做到这一点,我尝试了很多不同的事情。
这是我正在使用的规则,我正在尝试将 okHttpClient 注入(inject)其中
class OkHttpIdingResourceRule(application: Application) : TestRule {
/* My attempt below - but not working */
private val testApplication =
InstrumentationRegistry.getInstrumentation().targetContext.applicationContext
as AndroidTestGoWeatherApplication
// private val testApplication = application.applicationContext as AndroidTestGoWeatherApplication
private val component = testApplication.component as AndroidTestGoWeatherPresentationComponent
private val okHttpClient: OkHttpClient = component.okHttpClient()
private val idlingResource: IdlingResource = OkHttp3IdlingResource.create("okhttp", okHttpClient)
override fun apply(base: Statement?, description: Description?): Statement {
return object: Statement() {
override fun evaluate() {
IdlingRegistry.getInstance().register(idlingResource)
base?.evaluate()
IdlingRegistry.getInstance().unregister(idlingResource)
}
}
}
}
这是我的 AndroidTestGoWeatherApplication
class AndroidTestGoWeatherApplication : GoWeatherApplication(), HasActivityInjector {
@Inject
lateinit var activityInjector: DispatchingAndroidInjector<Activity>
override fun activityInjector(): AndroidInjector<Activity> = activityInjector
}
我的申请
open class GoWeatherApplication : Application(), HasActivityInjector, HasSupportFragmentInjector, HasServiceInjector {
@Inject
lateinit var dispatchingAndroidActivityInjector: DispatchingAndroidInjector<Activity>
@Inject
lateinit var dispatchingAndroidFragmentInjector: DispatchingAndroidInjector<Fragment>
@Inject
lateinit var dispatchingAndroidServiceInjector: DispatchingAndroidInjector<Service>
lateinit var component: GoWeatherComponent
override fun onCreate() {
super.onCreate()
component = DaggerGoWeatherComponent
.builder()
.application(this)
.build()
component.inject(this)
}
override fun activityInjector(): AndroidInjector<Activity> {
return dispatchingAndroidActivityInjector
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
return dispatchingAndroidFragmentInjector
}
override fun serviceInjector(): AndroidInjector<Service> {
return dispatchingAndroidServiceInjector
}
}
我的主要应用组件
GoWeatherComponent
@Singleton
@Component(modules = [
AndroidSupportInjectionModule::class,
ActivityBuilder::class,
NetworkModule::class,
GoWeatherApplicationModule::class])
interface GoWeatherComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: GoWeatherApplication): Builder
fun build(): GoWeatherComponent
}
fun inject(application: GoWeatherApplication)
}
我的测试应用程序组件
@Singleton
@Component(modules = [
AndroidSupportInjectionModule::class,
TestNetworkModule::class,
TestGoWeatherApplicationModule::class,
TestForecastModule::class])
interface AndroidTestGoWeatherPresentationComponent : AndroidInjector<AndroidTestGoWeatherApplication> {
@Component.Builder
abstract class Builder : AndroidInjector.Builder<AndroidTestGoWeatherApplication>() {
abstract fun applicationModule(TestApplicationModule: TestGoWeatherApplicationModule): Builder
abstract fun testNetworkModule(testNetworkModule: TestNetworkModule): Builder
}
fun okHttpClient(): OkHttpClient
}
这是我创建 OkHttpClient 的 TestNetworkModule
@Module
class TestNetworkModule {
@Singleton
@Provides
fun httpLoggingInterceptor(): HttpLoggingInterceptor {
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.level = if(BuildConfig.DEBUG) {
HttpLoggingInterceptor.Level.BODY
}
else {
HttpLoggingInterceptor.Level.NONE
}
return loggingInterceptor
}
@Singleton
@Provides
fun provideOkHttpClient(httpLoggingInterceptor: HttpLoggingInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.connectTimeout(2, TimeUnit.SECONDS)
.readTimeout(2, TimeUnit.SECONDS)
.build()
}
@Named("TestBaseUrl")
@Singleton
@Provides
fun provideBaseUrlTest(): String =
"http://localhost:8080/"
@Singleton
@Provides
fun provideRetrofit(@Named("TestBaseUrl") baseUrl: String, okHttpClient: OkHttpClient?): Retrofit {
return Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient!!)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
}
}
我的 Activity 生成器
@Module
abstract class ActivityBuilder {
@ContributesAndroidInjector(modules = [ActivityModule::class])
abstract fun injectIntoHomeActivity(): ForecastActivity
@ContributesAndroidInjector(modules = [ActivityModule::class, ForecastModule::class])
abstract fun injectIntoForecastFragment(): ForecastFragment
}
我的主要 Activity
class ForecastActivity : AppCompatActivity(), ForecastView, RetryListener, LocationUtilsListener {
companion object {
const val WEATHER_FORECAST_KEY = "weatherForecast"
}
@Inject
lateinit var forecastPresenter: ForecastPresenter
@Inject
lateinit var location: LocationUtils
private var fragmentManager: FragmentManager? = null
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
}
}
我的仪器测试
@RunWith(AndroidJUnit4::class)
class ForecastActivityAndroidTest {
@Inject
lateinit var okHttpClient: OkHttpClient
@get:Rule
val okHttpIdingResourceRule = OkHttpIdingResourceRule(InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as AndroidTestGoWeatherApplication)
@get:Rule
val activityRule = ActivityTestRule(ForecastActivity::class.java, false, false)
private val mockWebserver: MockWebServer by lazy {
MockWebServer()
}
@Before
fun setUp() {
val testApplication =
InstrumentationRegistry.getInstrumentation().targetContext.applicationContext
as AndroidTestGoWeatherApplication
DaggerAndroidTestGoWeatherPresentationComponent
.builder()
.applicationModule(TestGoWeatherApplicationModule())
.create(testApplication)
.inject(testApplication)
mockWebserver.start(8080)
}
@After
fun tearDown() {
mockWebserver.shutdown()
}
@Test
fun should_load_five_day_forecast() {
loadFromResources("json/fivedayforecast.json")
mockWebserver.enqueue(MockResponse().setBody(loadFromResources("json/fivedayforecast.json")))
ActivityScenario.launch(ForecastActivity::class.java)
/* do some testing here *
}
}
提前致谢
最佳答案
我认为您正在以错误的方式将 OkHttpClient
依赖项注入(inject)到 OkHttpIdingResourceRule
中。
来自 Dagger 2 文档:
Constructor injection is preferred whenever possible...
你拥有 OkHttpIdingResourceRule
所以你真的应该在这里进行构造函数注入(inject)。
通过将构造函数更改为如下所示,允许 Dagger 为您构造 OkHttpIdingResourceRule
:
class OkHttpIdingResourceRule @Inject constructor(application: Application, okHttpClient: OkHttpClient)
由于 OkHttpClient
已经在您的对象图中,我会将 OkHttpIdingResourceRule
注入(inject)您的测试 而不是 OkHttpClient
综上所述,我认为您的代码的其他部分仍然存在一些问题,但如果不运行它并亲自查看错误,我无法确认它们。例如,如果您计划以这种方式注入(inject)此测试,那么您必须在测试组件上使用这样的方法:
void inject(ForecastActivityAndroidTest 测试);
编辑:
我再次查看了您的规则,看起来您真正感兴趣的是注入(inject) IdlingResource
。如果是这种情况,您应该将构造函数更改为如下所示:
class OkHttpIdingResourceRule @Inject constructor(idlingRes: IdlingResource)
从那里您可以做的是在您的 TestNetworkModule
中创建一个为您创建它的配置方法:
@Provides
IdlingResource providesIdlingResource(OkHttpClient okHttpClient {
return OkHttp3IdlingResource.create("okhttp", okHttpClient)
}
关于android - 为仪器测试注入(inject) espresso 规则的依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56704449/
我在 gobject 上阅读了一个维基百科页面,上面写着, Depending only on GLib and libc, GObject is a cornerstone of GNOME and
如何注册一个依赖属性,其值是使用另一个依赖属性的值计算的? 由于 .NET 属性包装器在运行时被 WPF 绕过,因此不应在 getter 和 setter 中包含逻辑。解决方案通常是使用 Proper
我一直在尝试将 ActionbarSherlock maven 依赖项添加到我的项目中 com.actionbarsherlock library 4.2.0 在我的 po
http://tutorials.jenkov.com/ood/understanding-dependencies.html#whatis说(强调我的): Whenever a class A us
我对所有这些魔法有点不清楚。 据我了解,依赖属性是从 DependencyObject 继承的,因此存储值: 如果分配了值(在本地字典中),则在实例本身中 或者如果未指定值,则从指向父元素的链接中获取
我刚刚更新了在 ASP.NET Framework 4.5.2 版上运行的 MVC Web 应用程序。我正在使用 Twilio 发送 SMS 消息: var twilio = new TwilioRe
我刚刚发现了一件令人生畏的事情。 spring 依赖坐标有两个版本。 项目依赖于 spring mvc 和 spring flow。有两组并行的依赖项。 Spring MVC 具有以下方案的依赖项
我正在尝试包含 的 maven 依赖项 org.jacorb jacorb 2.3.1 依赖已解决,但它导致另一个依赖 picocontainer 出现问题: [ERROR
我正在尝试在 Haskell 项目中包含特定版本的库。该库是住宿加早餐型的(用于 martix 操作),但我需要特定的 0.4.3 版本,该版本修复了乘法实现的错误。 所以,我的 stack.yaml
有谁知道如何制作依赖的 UIPickerView.例如,当我选择组件一的第 2 行时,组件二的标题会发生变化吗? 我在互联网上查找过,没有真正的答案,我尝试过使用 if 和 switch 语句,但它们
我正在编写一个用于验收测试的项目,由于各种原因,这依赖于另一个打包为 WAR 的项目。我已成功使用 maven-dependency-plugin 解压 WAR,但无法让我的项目包含解压的 WEB-I
或多或少我在 session 上大量构建我的网站(特别是重定向用户等),我很好奇这是否是一种危险的做法。禁用浏览器 cookie 保存的用户的大致比例是多少?我愿意接受任何建议:) 谢谢 最佳答案 s
开始玩 Scala futures,我被依赖的 futures 困住了。 让我们举个例子。我搜索地点并获得 Future[Seq[Place]]。对于这些地点中的每一个,我搜索最近的地铁站(该服务返回
或多或少我在 session 上大量构建我的网站(特别是重定向用户等),我很好奇这是否是一种危险的做法。禁用浏览器 cookie 保存的用户的大致比例是多少?我愿意接受任何建议:) 谢谢 最佳答案 s
我有一个二进制文件,需要一些 *.so 文件才能执行。现在,当我尝试在一些旧机器上执行它时,它会显示 /lib/libc.so.6: version `GLIBC_2.4' not found 如何将
我尝试使用 Dygraph 来表示图表,我在 https://github.com/danvk/dygraphs 中找到了代码,但是它有太多的依赖文件,我觉得很烦人。是否有一个文件可以容纳所有必需的
我正在处理一个 javascript 文件,该文件 a) 声明一个具有函数的对象,并且 b) 使用它期望在外部声明的散列调用该对象的 init 函数。我的 Jasmine 规范提示它找不到哈希,因为它
最近我一直在学习 Angular 并且进展顺利,但是关于依赖注入(inject)的一些事情我仍然不清楚。 是否有任何理由在我的 app.js 文件中声明我的应用程序的其他部分(服务、 Controll
考虑一个名为 foo 的表,它有 id (PRIMARY & AUTO_INCREMENT) 列。我正在向该表中插入一行,挑战从此时开始。 $db->query("INSERT INTO `foo`
我正在使用级联下拉 jquery 插件。 (https://github.com/dnasir/jquery-cascading-dropdown) 我有两个下拉菜单。 “客户端”和“站点”。 根据您
我是一名优秀的程序员,十分优秀!