代码之家  ›  专栏  ›  技术社区  ›  Mike Martin

使用MobX store循环引用进行设置测试

  •  2
  • Mike Martin  · 技术社区  · 8 年前

    我正试图为我的MobX商店搞清楚如何使用Jest进行测试。

    我正在使用Mobx、React和Jest。

    class ConfigStore {
        constructor(RootStore) {
            this.rootStore = RootStore;
            this.config = {};
        }
    }
    class DataStore {
        constructor(RootStore) {
            this.config = RootStore.config;
        }
    }
    class UIStore {
        constructor(RootStore) {
            this.config = RootStore.config;
            this.data = RootStore.data;
        }
    }
    class RootStore {
        constructor() {
            this.config = new ConfigStore(this);
            this.ui = new UIStore(this);
            this.data = new DataStore(this);
        }
    }
    

    我的店铺设置正确吗?

    如果是这样的话,在将商店传递给提供商之前,最好的测试方法是什么?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Joel Harkes    8 年前

    你的问题很不清楚。在单元测试中,您到底想测试这些存储区的哪些内容?您无法真正测试数据本身。

    我的建议:

    链接到门店

    与其使用设置单个属性,不如保留整个存储:

    class DataStore {
        constructor(RootStore) {
            this.configStore = RootStore;
        }
    }
    

    这样,您可以确保始终正确更新和观察属性。

    如果需要,您可以始终在较低级别的商店中拥有财产:

    class DataStore {
        constructor(RootStore) {
            this.configStore = RootStore;
        }
        get config() {
           return this.configStore.config;
        }
    }
    

    摘要

    如果使用typescript将存储抽象为接口,则存储更易于测试:

    class DataStore {
        constructor(store: IConfigStore) {
            this.configStore = store;
        }
    }
    interface IConfigStore {
         config: Config;
    }
    

    使用存储库模式

    对于每个存储,使存储库可注入,以便存储所完成的所有api调用实际上都在该存储库中完成:

    class RootStore {
        constructor(repository) {
            this.repostiory = repository;
            this.config = new ConfigStore(this);
            this.ui = new UIStore(this);
            this.data = new DataStore(this);
            this.initializeData();
        }
        async initializeData(){
             this.config = await this.repository.getConfig();
        }
    }
    

    通过这种方式,您可以轻松地模拟存储库以提供静态日期,这样就不需要进行任何api调用。

    保持您的react组件纯净

    您真正想要进行单元测试的react组件。确保他们不直接使用mobx商店,但您使用 inject() 函数生成第二个类: https://github.com/mobxjs/mobx-react#inject-as-function

    这样,您的组件就更易于测试和独立使用:

    const PureReactComponent = ({ name }) => <h1>{name}</h1>
    
    const SimpleMobxComponent = inject(stores => ({
        name: stores.userStore.name
    }))(PureReactComponent)
    
    // usage:
    render() {
      return <SimpleMobxComponent/>
    }