茉莉花单元测试中的模拟助手 类

Mock helper classes in jasmine unit test

我想对使用助手 class 的 angular 组件进行单元测试。助手 class 及其功能不应成为此测试的一部分,而是应进行模拟。 该组件可能如下所示:

import { MyHelperClass } from "./my-helper-class";

export class MyComponent {
    public doStuff() {
        const helper = new MyHelperClass();
        if (helper.check()) {
            // code I want to test
        }
    }
}

我想在单元测试中排除 helper.check() 的功能,并假设它是 returns true(或在第二次测试中为 false)。所以我希望我的测试看起来像这样:

it("#doStuff should do something, assuming helper.check() is true, () => {
    // make constructor of MyHelperClass return a Mock
    // (or somehow spy on helper.check() and return true?) 

    expect(component.doStuff()).toBe(someValue);
});

您可以设置一个间谍来模拟函数调用和 returns 您想要 check() 的任何值。它还可以让您检查该函数是否(例如,间谍实际上被调用了多少次等)。

棘手的部分是,如果您没有 class 的实例,则需要在 class 的 prototype 上设置间谍。

看看这段代码(dummyVariable只是一个变量,用来测试check()之后的代码是否已经执行):

it('doStuff should do something, assuming helper.check() is true', () => {
  // test the before value
  expect(component.dummyVariable).toBe(false);

  // set up the spy and make it return true
  const spy = spyOn(MyHelperClass.prototype, 'check').and.returnValue(true);

  // call our function
  component.doStuff();

  // check the after value
  expect(component.dummyVariable).toBe(true);

  // check if our spy/mocked function was actually called
  expect(spy).toHaveBeenCalledTimes(1);
});

// same thing as above but this time our spy returns false
it('doStuff should do something, assuming helper.check() is false', () => {
  expect(component.dummyVariable).toBe(false);

  const spy = spyOn(MyHelperClass.prototype, 'check').and.returnValue(false);
  component.doStuff();

  expect(component.dummyVariable).toBe(false);
  expect(spy).toHaveBeenCalledTimes(1);
});

You can find a working example here.