在 TypeScript 中模拟只读 Flux 存储属性



我正在使用React,Flux和TypeScript创建一个应用程序。我正在使用业力和茉莉花进行测试。

我有一个商店,如下所示:

class MemberStore {
    private _members:Member[];
    public get members():Member[] { return this._members; }
}

与所有 Flux 存储一样,数据是只读的,并通过操作处理程序(未显示(而不是资源库进行修改。

我想在依赖于MemberStore的代码单元测试中模拟此数据存储。但是,由于members是只读的,因此我无法执行以下操作:

var mockMemberStore:MemberStore = jasmine.createSpyObj("MemberStore");
mockMemberStore.members = [/*mock members*/];

上面的代码实际上发出工作 JS,因为mockMemberStore实际上不是 MemberStore 的实例,而是一个 Jasmine 间谍对象(并且createSpyObj返回 any (。但是,它会在mockMemberStore.members = []上生成编译错误,因为它是只读属性。

编辑:所以事实证明我误读了错误,并不是这段代码给出了错误。这不是编译错误,而是运行时错误。令人惊讶的是,TSC 并不关心我是否在编译时为 members 分配一个值,即使 它是只读的。在上面的例子中,我替换了MemberStore 完全用茉莉花SpyObj,它有效。相反,如果我只是尝试 spyOn MemberStore的真实版本,那就是我看到运行时错误的时候 无法分配members。例

我可以将其更改为 var mockMemberStore:any ,或者像 (<any> mockMemberStore).members = [] 一样使用强制转换,但随后编译器不会members视为对ModelStore/members的引用,因此所有静态类型检查都将丢失(并且诸如"查找引用"和"重构/重命名"之类的东西不起作用(。这里使用什么方法?

你应该能够写:

(mockMemberStore as any).members = [""];

这不会更改将来对 mockMemberStore 的任何引用的类型。因为这是一个单元测试,所以代码不需要像通常那样完美。重要的是,如果您引入错误,它将失败,在这种情况下,它将失败:如果您执行无效的重构,renamedMembers将不再设置,测试应该会爆炸,您将能够修复它。

这并不理想,因为你确实丢失了查找用法,但它并不像其他语言中那样糟糕(模拟只读对象是出了名的麻烦(。

接口对此

很有用:

interface IMemberStore {
    members: Member[];
}
class MemberStore implements IMemberStore {
    private _members:Member[];
    public get members():Member[] { return this._members; }
}
class MockMemberStore implements IMemberStore {
    members: Member[];
}

在大多数应用程序中使用 IMemberStore,使用 MemberStore 作为实现,并在单元测试中使用MockMemberStore

最新更新