【问题标题】:Jasmine & Angular: Mocking nested methods of Class under TestJasmine & Angular:模拟被测类的嵌套方法
【发布时间】:2020-03-21 21:01:27
【问题描述】:

尊敬的社区...

我遇到了下面这个问题,感觉很简单,但是找不到解决办法……

我正在 Angular 中测试一个控制器类。这是具有大量依赖项的遗留代码,我只想编写一个单元测试不模拟所有依赖项

我正在寻找模拟嵌套函数的解决方案,即我调用一个方法,并期望嵌套方法被成功调用,没有实际调用它。

一个样本...

my-controller.ts

export class MyController {

   constructor () {}
   public init() {
      /* doStuff */
      this.initializeMyObject();
   }

   private initializeMyObject(): void {
     /*  doOtherStuff  */
   }
}

my-controller.spec.ts

describe('MyController', () => {
  let controller: MyController;

  configureTestSuite(() => {
    TestBed.configureTestingModule({
      schemas: [NO_ERRORS_SCHEMA],
      imports: [/*.. module imports ..*/],
      providers: [ MyController ],
    });
  });

  beforeEach(() => {
    controller = TestBed.get(MyController);
  });

  it('completion should be called', () => {
    // arrange
    spyOn(controller, 'initializeMyObject');

    // act
    controller.init();

    // assert
    expect(controller.initializeMyObject).toHaveBeenCalled();
  });

});

我知道我们通常不模拟被测试类的方法,但我从其他编程语言(如 Java)知道它可以工作,我只是好奇如何做到这一点(除此之外,模拟所有嵌套依赖将是总开销...)。

我读过一些关于 jasmine.createSpyObj 的文章,但我怀疑解决方案会类似于 jasmine.createSpyObj('this', ['initializeMyObject']),如果我错了,请纠正我。

(这不是我正在寻找的答案的一部分,但如果存在一些第三方库,我会很高兴有建议并跟进。)

我们将不胜感激。 干杯。

【问题讨论】:

    标签: angular unit-testing jasmine


    【解决方案1】:

    使用 Jasmine 模拟单个类方法有不同的方法。这里有一些例子。

    当方法没有返回值时(void返回类型)。

    spyOn(object, 'method-name').and.callFake(() => null); 
    

    什么时候方法应该返回一个给定的值。

    spyOn(object, 'method-name').and.returnValue(value); 
    

    当方法接受参数并应返回基于它们的计算值时。

    spyOn(object, 'method-name').and.callFake((p1, p2) => {
        // compute value
        return value;
    }); 
    

    【讨论】:

    • 但是如何测试该方法是否真的被调用了?如何验证:expect(object.method-name).toHaveBeenCalled()?
    • expect(object.method-name).toHaveBeenCalled() 就好了
    • 能否分享MyController.initMyController.initializeMyObject方法的全部内容?也许你在那里执行一些异步工作。
    • 请考虑这个答案,因为您正在监视私有方法:stackoverflow.com/a/48734437/2358409
    • 我确实有一个 asychronos 函数,但是这个函数被嘲笑了。我在调用initializeMyObject 之前收到了一个console.log 输出,所以它肯定会到达那里。 spyOn<any>MyController.prototype 也不成功
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    相关资源
    最近更新 更多