Javascript 如何用Jasmine模拟Angular中的服务依赖关系? 我一直在搜索Google这段时间,对于我认为相当琐碎的事情,没有快速简洁的答案。

Javascript 如何用Jasmine模拟Angular中的服务依赖关系? 我一直在搜索Google这段时间,对于我认为相当琐碎的事情,没有快速简洁的答案。,javascript,angular,jasmine,Javascript,Angular,Jasmine,我有一个服务serviceToTest,它有一个依赖项serviceDep,通过Angular的DI注入 服务看起来像这样 export class ServiceToTest { constructor(private _dep: ServiceDep){} serviceMethod() {}; } 我想对serviceMethod方法进行单元测试,为此我需要实例化服务并模拟依赖关系。依赖项不需要做任何事情,只需要允许实例化服务。我想要测试的方法不需要执行依赖项 如何设置

我有一个服务
serviceToTest
,它有一个依赖项
serviceDep
,通过Angular的DI注入

服务看起来像这样

export class ServiceToTest {
    constructor(private _dep: ServiceDep){}

    serviceMethod() {};
}
我想对
serviceMethod
方法进行单元测试,为此我需要实例化服务并模拟依赖关系。依赖项不需要做任何事情,只需要允许实例化服务。我想要测试的方法不需要执行依赖项


如何设置模拟以满足服务的构造函数要求?

您可以提供自己的模拟服务来代替实际服务:

describe('ServiceToTest ', () => {
  beforeEach(() => TestBed.configureTestingModule({
    imports: [],
    providers: [{ provide: ServiceToTest, useClass: ServiceToTestMock }]
  }));

您可以提供自己的模拟服务来代替实际服务:

describe('ServiceToTest ', () => {
  beforeEach(() => TestBed.configureTestingModule({
    imports: [],
    providers: [{ provide: ServiceToTest, useClass: ServiceToTestMock }]
  }));
下面是一些选项

选项一

it('should return value', () => {
  const serviceDepSpy = spyOn(Testbed.inject(ServiceDep), 'serviceMethod').returnValue(of(MOCK_VALUE));

  component.ngOnInit(); // assuming your method is called on init. 

  expect(serviceDepSpy).toHaveBeenCalled();
});

要做到这一点,必须通过间谍进行:

it('should return value', () => {
  const serviceDepSpy = spyOn(Testbed.inject(ServiceDep), 'serviceMethod').returnValue(of(MOCK_VALUE));

  component.ngOnInit(); // assuming your method is called on init. 

  expect(serviceDepSpy).toHaveBeenCalled();
});

我引述:

喜欢间谍,因为他们通常是模拟服务的最简单方式

这允许您在单元测试级别(在每个测试中)轻松地进行模拟,并避免覆盖模拟服务(如果您使用
useClass
方法,这很容易成为一个问题

选项二

it('should return value', () => {
  const serviceDepSpy = spyOn(Testbed.inject(ServiceDep), 'serviceMethod').returnValue(of(MOCK_VALUE));

  component.ngOnInit(); // assuming your method is called on init. 

  expect(serviceDepSpy).toHaveBeenCalled();
});

useClass

当您在每个测试用例中总是返回相同的值时,这往往效果最好。如果您在每个测试中需要不同的模拟值,我会选择spies

选项三

useValue
当您需要硬编码一个值或导入的模拟对象,并在所有测试用例中使用相同的模拟值时,这种方法最为有效。就像
useClass
一样,它可能很难覆盖。

下面的一些选项

选项一

it('should return value', () => {
  const serviceDepSpy = spyOn(Testbed.inject(ServiceDep), 'serviceMethod').returnValue(of(MOCK_VALUE));

  component.ngOnInit(); // assuming your method is called on init. 

  expect(serviceDepSpy).toHaveBeenCalled();
});

要做到这一点,必须通过间谍进行:

it('should return value', () => {
  const serviceDepSpy = spyOn(Testbed.inject(ServiceDep), 'serviceMethod').returnValue(of(MOCK_VALUE));

  component.ngOnInit(); // assuming your method is called on init. 

  expect(serviceDepSpy).toHaveBeenCalled();
});

我引述:

喜欢间谍,因为他们通常是模拟服务的最简单方式

这允许您在单元测试级别(在每个测试中)轻松地进行模拟,并避免覆盖模拟服务(如果您使用
useClass
方法,这很容易成为一个问题

选项二

it('should return value', () => {
  const serviceDepSpy = spyOn(Testbed.inject(ServiceDep), 'serviceMethod').returnValue(of(MOCK_VALUE));

  component.ngOnInit(); // assuming your method is called on init. 

  expect(serviceDepSpy).toHaveBeenCalled();
});

useClass

当您在每个测试用例中总是返回相同的值时,这往往效果最好。如果您在每个测试中需要不同的模拟值,我会选择spies

选项三

useValue

当您需要硬编码一个值或导入的mock对象,并在所有测试用例中使用相同的mock值时,这种方法最为有效。就像
useClass
一样,它可能很难覆盖。

但是我应该用什么来实例化mock
ServiceToTestMock
?@Jake12342134它是在
ServiceToTest
的位置被注入的(您不需要实例),
ServiceToTestMock
可以像
class ServiceToTestMock{}
一样简单,如果您不需要调用任何实际的方法,那么我该如何实例化mock
ServiceToTestMock
的实例呢?@Jake12342134它被注入到
ServiceToTestMock
(您不需要实例),
ServiceToTestMock
可以像
class ServiceToTestMock{}
一样简单,只要您不需要调用任何实际的方法,就可以使用fakeAsync()从依赖于异步测试的组件读取很好的一点,
fakeAsync
是在您需要控制异步区域时使用的。我认为Jake在这种情况下不需要使用它。使用fakeAsync()从具有依赖项的组件读取到异步测试很棒的一点,
fakeAsync
是在需要控制异步区域时使用的。我认为Jake在这种情况下不需要使用它。