如何使用 spyOn 欺骗 Observable?

How to spoof Observable using spyOn?

我编写了通过 http:

请求 JSON 的服务
export class TodosService {
  constructor(private http: HttpClient) {}
  getTodos(): Observable<any> {
    return this.http.get<any>('https://jsonplaceholder.typicode.com/todos');
  }
}

从服务中为组件分配了一个值:

export class TodosComponent implements OnInit {
  todos: any;
 
  constructor(private todosService: TodosService) {}
 
  ngOnInit() {
    this.todosService.getTodos().subscribe((todos) => {
      this.todos = todos;
    });
  }
}

我想测试一下。有单元测试:

describe('Page1Component', () => {
  let component: Page1Component;
  let fixture: ComponentFixture<Page1Component>;
  let spy: any;
  let todosService: TodosService;
 
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [Page1Component],
      imports: [HttpClientModule],
      providers: [TodosService],
    }).compileComponents();
  });
 
  beforeEach(() => {
    fixture = TestBed.createComponent(Page1Component);
    component = fixture.componentInstance;
    fixture.detectChanges();
    todosService = TestBed.inject(TodosService);
  });
 
  it('should fill todos', () => {
    const todos = of([
      {
        completed: false,
        id: 1,
        title: 'title1',
        userId: 1,
      },
    ]);
    spyOn(todosService, 'getTodos').and.returnValue(todos);
    component.ngOnInit();
    expect(component.todos).toEqual(todos);
  });
});

我收到以下错误消息:

Expected [ Object({ completed: false, id: 1, title: 'title1', userId: 1 }) ] to equal Observable({ _isScalar: false, _subscribe: Function }).

我尝试使用以下模拟:

const todos = [
  {
    completed: false,
    id: 1,
    title: 'title1',
    userId: 1,
  },
];

但在这种情况下,我在 IDE 中得到以下弹出窗口:

Argument of type '{ completed: boolean; id: number; title: string; userId: number; }[]' is not assignable to parameter of type 'Observable'.

请帮我解决这个单元测试

您与您的尝试非常接近,但是您正在将一个数组与 expect 匹配器上的一个可观察对象进行比较。您需要比较 observable

的结果
  const data = [
    {
      completed: false,
      id: 1,
      title: 'title1',
      userId: 1,
    },
  ]
  const todosObservable = of(data);
  spyOn(todosService, 'getTodos').and.returnValue(todosObservable);
  component.ngOnInit();
  expect(component.todos).toEqual(data);

上面的代码片段可以正常工作,但我通常更喜欢使用 HttpClientTestingModule,它很方便,因为您不必经常模拟服务