Angular 单元测试 - 为单个测试更改模拟服务 class 的方法 return

Angular unit test - changing a mock service class's method return for individual tests

在我的单元测试中,我有一个正在使用的模拟服务 class,MockWorkflowService,它有一个方法 getActiveTask。大部分测试都需要此方法的默认功能,但是我需要一些测试来覆盖此方法并将其设置为 return null。但是我没有运气这样做(请参阅代码块底部的测试):

class MockWorkflowService {
  getActiveTask() {
    return new Action({
      name: 'test',
      value: 4
    })
  }
}

describe('MyComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        MyComponent
      ],
      providers: [
        TranslateService,
        { provide: WorkflowService, useClass: MockWorkflowService }
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should ...', () => {
    // TRYING TO DO SOMETHING LIKE
    MockWorkflowService.getActiveTask = () => null;
  });

})

我尝试做 MockWorkflowService.prototype.getActiveTask = () => null,它适用于我想覆盖它的单个测试,但是对于所有剩余的测试,方法 returns null。

非常感谢任何帮助,谢谢。

当您只想为该特定测试覆盖时,这就是您需要做的。您正在做的是覆盖该服务的所有实例,这是错误的。你可以关注这个:

// Define the service here: 
describe('MyComponent', () => {
  let workflowService: WorkFlowService // Add this line
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        MyComponent
      ],
      providers: [
        TranslateService,
        { provide: WorkflowService, useClass: MockWorkflowService }
      ]
    })
      .compileComponents();
  }));

// In before each, create an instance of the service
 beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    workFlowService = TestBed.get(WorkflowService); // Add this line
    // TestBed.get should be TestBed.inject if you're using Angular 9+
  });


it('should ...', () => {
  // Spy on the service and return null
  // This will call the mock service class and return null for this test case

  spyOn(workFlowService, 'getActiveTask').and.returnValue(null);
  component.yourComponentMethodName();
  expect(component.yourComponentMethodName).toHaveBeenCalled();
});