使用MobX存储循环引用进行安装测试

时间:2018-05-16 18:07:51

标签: javascript reactjs unit-testing jestjs mobx

我正在尝试用Jest测试我的MobX商店。

我正在使用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);
    }
}

我是否正确设置了商店?

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

1 个答案:

答案 0 :(得分:1)

你的问题很不清楚。您想在单元测试中测试这些商店到底是什么?你无法自己测试数据。

我的建议:

商店链接

而不是使用设置单个属性只保留整个商店:

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调用。

保持您的反应成分纯净

您真正想要进行单元测试的反应组件。确保他们不直接使用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/>
}