将匕首与意式浓缩咖啡搭配使用



我计划在我的应用程序多模块上创建浓缩咖啡测试,我即将创建第一个浓缩咖啡测试。但我看到的是,在我的程序上,我没有可以伪造的AppComponent。由于我想在我的功能模块上添加测试,我将从现在开始在那里创建TestAppTestRunner

我的特性模块上有一个FeatureComponent,它是通过ComponentFactoryApp注入的,所以我想创建一个这样的类:

@Component (
dependencies = [ MoreComponents::class],
modules = [ DataSourceModule::class ]
)
interface FeatureOneComponent { 
fun activityOneSubComponent(): FeatureOneActivity.Component.Factory
fun activityTwoSubComponent(): FeatureTwoActivity.Component.Factory
@Component.Factory
interface Factory {
fun create(
dependencies
):FeatureOneComponent
}
}
interface FeatureOneProvider {
fun getFeatureOneComponent(): FeatureOneComponent
}

///ACTIVITY
class FeatureOneActivity : AppCompatActivity() {
//this comes from Subcomponent is what I want to MOCK 
@Inject lateinit var presenter
//these comes from the factory and I have it mocked
@Inject lateinit var manager
override fun onCreate(){
(applicationContext as FeatureOneProvider).getFeatureOneComponent().activityOneSubComponent().create(this).inject(this)
}
}
@Subcomponent(modules = [ActivityOneModule::class]) <--- THIS I WANT TO MOCK
interface Component {
fun inject(activity: FeatureOneActivity)
@SubComponent.Factory
interface Factory {
fun create(@BindsInstance activity: FeatureOneActivity): Component
}
}
@Module
interface ActivityOneModule {
@Binds
fun bindPresenter(impl: PresenterImpl): Contract.Presenter    
}

测试

class MyTestApp : Application(), FeatureOneProvider {
override fun getFeatureOneComponent(): FeatureOneComponent {
return DaggerMockFeatureOneComponent.create()
}
}
@Component(
modules = [MockFeatureOneModules::class]
)
interface MockFeatureOneComponent : FeatureOneComponent {

//I NEED TO MOCK THE SUBCOMPONENT WITH `MockSubcomponent`
}
@Component 
object MockFeatureOneModules {
@Provides
fun providesManager() : MyManager = mock(MyManager)
}
//I want to use this module to replace the subcomponent of my activity
@Module
object MockSubcomponent() {
@Provides
fun providesFakePresenter() : FeatureOneContract.Presenter = mock { FeatureOneContract.Presenter::class.java }
}

为了更好地理解问题

当我运行测试并设置调试点时,我看到除了演示者之外的所有东西都被嘲笑了,这是因为演示者在中

@Subcomponent(modules = [ActivityOneModule::class]
interface Component {
fun inject(activity: FeatureOneActivity)
@SubComponent.Factory
interface Factory {
fun create(@BindsInstance activity: FeatureOneActivity): Component
}
}
@Module
interface ActivityOneModule {
@Binds
fun bindPresenter(impl: PresenterImpl): Contract.Presenter    
}

在我的测试组件中,我无法访问";覆盖";这个子组件,所以一切都被嘲笑,但这个子组件和我需要这个嘲笑。

我不知道这是否是最好的主意,但如果我没有误解你的话,你希望这个演示者返回mock {}。你可以做的改变是:

  1. 在TestComponent中将interface更改为abstract class
  2. 复制子组件并从真实组件扩展
@Component(
modules = [MockFeatureOneModules::class]
)
abstract class MockFeatureOneComponent : FeatureOneComponent {

abstract fun subcomponent() : MockComponent.FactoryMock
override fun activityOneSubComponent(): FeatureOneActivity.Component.Factory {
return subcomponent()
}
@Subcomponent
interface MockComponent : FeatureOneActivity.Component { 
@Subcomponent.Factory
interface FactoryMock : FeatureOneActivity.Component.Factory {
override fun create....
}
}
}

就这样,它应该起作用。

您的示例代码很难理解,实际问题也很复杂。但据我所知,你想为你的功能模块设置expresso测试,你需要为它设置dagger组件

所以,我可以给你一些指导方针和示例代码,这样你就可以非常简单地遵循和设置你的dagger架构来进行espresso测试。

首先,你需要设置/创建你的应用程序进行浓缩咖啡测试,如下所示:

class MyTestApplication : MyApplication() {
//Call this from MyApplication onCreate()
override fun initDaggerGraph() { 
component = DaggerTestAppComponent.builder()
.application(this)
.appLifecycle(appLifecycle)
.build()
component.inject(this)
}
}

然后创建这样的测试应用程序组件:

//Add all of your dependent modules in this TestAppModule
@Component(modules = [TestAppModule::class])
interface TestAppComponent : AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
@BindsInstance
fun appLifecycle(appLifecycle: AppLifecycle): Builder
fun build(): TestAppComponent
}
fun inject(activityTest: SomeActivityTest) //Your activity where to inject
}

此外,在启动以下活动时,请确保在测试活动类中初始化组件:

val component = MyApplication.instance.component as TestAppComponent
component.inject(this)

现在你已经完成了所有的设置,你的依赖性应该会得到解决,你的浓缩咖啡测试也应该会工作。

据我所知,您有多个模块、组件和子组件,但由于它们的大多数名称在您发布的代码中不完全匹配,也没有发布错误日志,所以我必须猜测哪里出了问题。

相反,不如做这样的事。

public interface SomeComponent {
WhateverClass1 provideWhatever1();
WhateverClass2 provideWhatever2();
WhateverRepository1 provideWhateverRepository1();
SomeOtherComponent getSomeOtherComponent();
// and so on and on
}

然后让你的生产组件看起来像这样:

@SomeComponentSingleton
@Component(modules = { ... },
dependencies = { ... })
public interface SomeProductionScopedComponent extends SomeComponent {
@Component.Builder
interface Builder {
// you know best what needs to go here
SomeProductionScopedComponent build();
}
}

和这个

@SomeComponentSingleton
@Component(dependencies = SomeComponent.class, modules =
{ ... })
public interface TestSomeComponent {
@Component.Builder
interface Builder {
Builder bindCoreComponent(SomeComponent coreComponent);
@BindsInstance
Builder bindContext(Context context);
TestSomeComponent build();
}
}

然后,假设您使用这些构建器手动实例化组件,只要它们依赖于接口(SomeComponent(,您就应该能够将ProductionSomeComponent或TestSomeComponent绑定到您的模块中。

有道理还是暗示?

最新更新