当前位置: 首页 > 知识库问答 >
问题:

Dagger 2 Android子组件覆盖

甘西岭
2023-03-14

如果我创建了一个子组件,我想在dagger的特定功能中使用该子组件,可以这样说:

@TransactionsActivityScope
@Subcomponent(modules = {TransactionsModule.class})
public interface TransactionsComponent {

    TransactionsManager provideTransactionsManager();

    void inject(TransactionsFragment transactionsFragment);

    void inject(TransactionsFilterActivity transactionsFilterActivity);
}

我在主应用程序组件中添加了一个加号:

TransactionComponent plusTransactionSubcomponent(TransactionModule transactionModule);

并在片段中使用它:公共类TransactionsFraank{……

 @Override
    protected void setupGraph(DaggerAppGraph graph) {
        graph.plusTransactionsSubcomponent(new TransactionModule()).inject(this);
    }
}

在浓咖啡测试中,覆盖此子组件的正确方法是什么。对于组件和组件依赖关系,直接编写一个TestAppComponent,扩展“原始”组件并在其中插入MockModules,但是如何使用子组件干净地完成这一工作?

我还看了DaggerAndroidInjector.inject(this);组件和活动组件的解决方案是相似的,但我认为没有办法对子组件和片段进行干净的解决方案。我相信编写方法并覆盖活动/片段组件设置器并在那里进行覆盖是次优的。我错过了什么吗?

共有2个答案

昌和悦
2023-03-14

在我们的应用中,我们使用额外的包装器来管理名为< code>ComponentStorage的子组件范围。我们的< code >应用程序创建这个对象,< code>TestApplication覆盖它并返回< code > TestComponentStorage 。因此,我们可以轻松地覆盖方法< code > plusTransactionSubcomponent 并返回带有模拟模块的组件。

public class ComponentStorage {
    protected TransactionComponent transactionComponent;
    protected AppGraph graph;

    public ComponentStorage() {
        graph = buildGraph();
    }

    public TransactionComponent plusTransactionSubcomponent(TransactionModule transactionModule) {
        if(transactionComponent == null) {
            transactionComponent = graph.plusTransactionsSubcomponent(new TransactionModule());
        }
        return transactionComponent;
    }

    public AppGraph buildGraph() {
        return DaggerAppGraph.create();
    }

    // to manage scope manually
    public void clearTransactionSubcomponent() {
        transactionComponent = null;
    }
}


public class TestComponentStorage extends ComponentStorage{

    @Override
    public TransactionComponent plusTransactionSubcomponent(TransactionModule transactionModule) {
        if(transactionComponent == null) {
                                                                        // mocked module
            transactionComponent = graph.plusTransactionsSubcomponent(new TestTransactionModule());
        }
        return transactionComponent;
    }
}

在客户端代码中,您将使用它componentStorage.plusTransactionsSubcomponent(new TransactionModule())。注入(this)

如果您需要完整的代码,请发表评论,我将为此创建要点。

齐文栋
2023-03-14

这在原来的匕首上很容易,但在匕首2上就不行了。然而,这里有一个解决方案:用完全相同的类名、文件名和位置创建一个模仿的风格和一个模仿的模块。现在使用模仿风格运行您的ui测试。

您可以在我的测试项目中看到它是如何完成的。

> < li>

我在应用程序中使用real模块。位于src/prod/.../ContentRepositoryModule.java

我在测试时使用模拟模块:位于src/mock/../ContentRepositoryModule.java

然后,我的模拟模块引用FakeContentRepository,正如您计划的那样。

在build.gradle:

flavorDimensions "api", "mode"
productFlavors {
   dev21 {
       // min 21 has faster build times, also with instant build
       minSdkVersion 21
       dimension "api"
   }
   dev16 {
        minSdkVersion 16
        dimension "api"
   }
   mock {
        dimension "mode"
   }
   prod {
        minSdkVersion 16
        dimension "mode"
   }
}


// remove mockRelease:
android.variantFilter { variant ->
    if (variant.buildType.name == 'release'
            && variant.getFlavors().get(1).name == 'mock') {
        variant.setIgnore(true);
    }
}

所以再说一遍:这个测试项目显示了一切。

 类似资料:
  • 我在根目录中有一个htaccess文件,在电影文件夹中有另一个htaccess文件。我想停止所有重写URL或影响“电影”文件夹的条件。我在电影文件夹访问中有一些其他规则。 我的根访问权限如下所示 我的子目录电影文件夹htaccess 上面的代码只是我最初的htaccess的一部分

  • 程序屏幕截图 我正在制作动画。当我按下按钮时,它会触发一个动画,使从右侧浮动。当鼠标离开时JPanel退出动画),但问题是我在动画上有一个。因此,当我将鼠标移出动画时,面板不仅会消失,而且当我在按钮(这是面板的一个组件)上移动鼠标时,面板也会消失,这意味着当我想单击按钮时,它会消失,因为当鼠标离开时,就会被触发。 请看上面的图片,我在其中标记了某些区域。 < li >是JPanel,当我将鼠标移到

  • 我是ReactJS的新手,我在ES2015的基础上学习它。大多数例子是ES5。我的问题似乎是渲染子组件。 我的子组件是一个文本字段 我的父组件称为AddressBox,将包含许多子控件。如果displayMode为true,则它应该呈现一个范围,如果为false,则它应该呈现一个表单控件。 地址框代码为: 当我尝试渲染这些控件时,会出现以下错误: 警告:作出反应。createElement:类型不

  • 我有一个在父组件中生成的事件,子组件必须对此作出反应。我知道在中不建议使用这种方法,我必须执行emit,这非常糟糕。所以我的代码是这个。 正如您所看到的,在无限滚动上被触发,事件被发送到子组件搜索。不仅仅是搜索,因为它是根,所以它正在向每个人广播。 什么是更好的方法。我知道我应该使用道具,但我不知道在这种情况下我该怎么做。

  • 场景 我有一个父组件,里面包含一个子组件,子组件传入了一个对象,假设对象是字面量。当我的父组件更新时,子组件也会更新。导致不必要的渲染。 尝试 1.通过使用React.memo包裹子组件,作用是父组件更新,子组件只有当props变化才变化。结果发现还是不对。。。。分析了一下原因是,当父组件更新时候,传入到子组件的的引用发生了变化,虽然值是相同的。。。咋搞

  • 我正在尝试使用fscanf加载一些结构数组的默认值,这看起来像 数据按如下方式存储在文本文件中(使用不同的值重复多次): 我用fscanf/fscanf_s(尝试两者)读取的值如下: 然而,VS2012在最后抛出了一个异常,称列表已损坏。调试显示,在阅读了上述示例文本的前四行后,结构的“map”部分包含以下内容 其中X是未初始化的值。 似乎fscanf正在试图“null terminate”我的整