Sinon: 无法在具有私有成员的类上创建 StubInstance

创建于 2019-01-04  ·  3评论  ·  资料来源: sinonjs/sinon

描述错误
如果我sinon.createStubInstance(X)其中 X 是一个至少有一个私有成员的类,我会收到如下错误:

'SinonStubbedInstance 类型的参数' 不能分配给 'Foo' 类型的参数。
“SinonStubbedInstance”类型中缺少属性“_private”' 但在 'Foo' 类型中是必需的。

describe('SinonTest', () => {
  class Foo {
    public talk() {
      return 'hi';
    }
    private _private() {
      return null;
    }
  }

  function printSpeech(foo: Foo) {
    console.log(foo.talk());
  }
  it('should allow you to pass a stub as a the original', () => {
    const mockFoo = sinon.createStubInstance(Foo);

    printSpeech(mockFoo);
  });
});

重现
重现行为的步骤:

  1. 用 mocha 和 sinon 建立一个项目。
  2. 创建单元测试规范文件
  3. 粘贴上面的代码片段并添加所需的任何导入
  4. 查看与printSpeech(mockFoo)一致的错误

预期行为
我希望这可以正常工作。 我不关心 _private(),也不打算直接测试它的行为,但它不应该导致构建时错误。 Jasmine 用jasmine.createSpyObj支持这种情况,尽管 jasmine 的实现还有其他缺陷。

背景(请填写以下信息):

  • 库版本:sinon:7.2.2,@types/sinon:7.0.3
  • 环境:WSL Ubuntu 16.04,节点 10

  • 您正在使用的其他库:Mocha 5.2.0

编辑:这是一个堆栈闪电战https://stackblitz.com/edit/typescript-nfbgno?file=index.ts

它抱怨 process.stdout 因为它在浏览器中运行,但这并不重要,因为实际问题是编译时

最有用的评论

这不是一个明确的解决方案,但我设法通过以下功能解决了这个问题:

import { createStubInstance, StubbableType, SinonStubbedInstance, SinonStubbedMember } from 'sinon';

export type StubbedClass<T> = SinonStubbedInstance<T> & T;

export function createSinonStubInstance<T>(
  constructor: StubbableType<T>,
  overrides?: { [K in keyof T]?: SinonStubbedMember<T[K]> },
): StubbedClass<T> {
  const stub = createStubInstance<T>(constructor, overrides);
  return stub as unknown as StubbedClass<T>;
}

显然,这并没有实现任何私有方法,因此您不能(也不应该按照设计)调用它们。 通过使用这个包装函数,您可以完成类中所有公共函数/成员以及 sinon 的存根辅助函数和 StubbedClass 的代码完成是在您的测试中用作 T 的有效类型。

所有3条评论

这是一个打字稿问题。我们不会花时间研究这个,因为我们不明确支持 Typescript。 Typescript 以某种方式支持私有成员是其类型系统的一个属性,并且可以通过多种方式实现。当我使用 Typescript 时,我经常通过去 Typescript 游乐场并检查输出以了解它的作用来解决此类问题。这也是你需要做的。

这不是一个明确的解决方案,但我设法通过以下功能解决了这个问题:

import { createStubInstance, StubbableType, SinonStubbedInstance, SinonStubbedMember } from 'sinon';

export type StubbedClass<T> = SinonStubbedInstance<T> & T;

export function createSinonStubInstance<T>(
  constructor: StubbableType<T>,
  overrides?: { [K in keyof T]?: SinonStubbedMember<T[K]> },
): StubbedClass<T> {
  const stub = createStubInstance<T>(constructor, overrides);
  return stub as unknown as StubbedClass<T>;
}

显然,这并没有实现任何私有方法,因此您不能(也不应该按照设计)调用它们。 通过使用这个包装函数,您可以完成类中所有公共函数/成员以及 sinon 的存根辅助函数和 StubbedClass 的代码完成是在您的测试中用作 T 的有效类型。

@pauloavelar答案仍然是推荐的解决方法吗?

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

OscarF picture OscarF  ·  4评论

zimtsui picture zimtsui  ·  3评论

akdor1154 picture akdor1154  ·  4评论

NathanHazout picture NathanHazout  ·  3评论

optimatex picture optimatex  ·  4评论