首页 > 解决方案 > 对具有许多依赖项 Angular 的服务进行单元测试

问题描述

我想知道如何测试以下服务,它在构造函数中有两个依赖项。

我不知道如何创建测试环境,如何在测试中实现MatDiaglog

我应该发出虚假请求来测试此功能吗?一般来说,单元测试中的良好做法是什么,场景是什么?

@Injectable()
export class FacultiesService {
  constructor(
    private apiService: ApiService,
    private dialog: MatDialog) { }


  openAddFacultyDialog(data = null) {
    const dialogRef = this.dialog.open(CreateEditComponent, {
      width: '400px',
      data
    });
    return dialogRef.afterClosed();
}

  createFaculty(faculty: Faculty) {
    return this.apiService.createEntity('Faculty', faculty);

  }
}

 @Injectable({
  providedIn: 'root'
})

export class ApiService {
  constructor(private http: HttpClient) { }

  createEntity(entity: string, payload): Observable<any> {
    return this.http.post(`${this.apiURI}${entity}/insertData`, payload);
  }

标签: angularunit-testing

解决方案


进行单元测试时要记住的关键是您应该始终孤立地测试功能。

如果您想FacultiesService在您的场景中进行测试,那么应该监视或模拟其他服务。

// you can pass data using this mockMatDialog
const mockMatDialog = {}
let apiServiceSpy = jasmine.createSpyObj('ApiService', ['createEntity']);
beforeEach(() => {
  TestBed.configureTestingModule({
    providers: [{
        provide: ApiService,
        useValue: apiServiceSpy
      },
      {
        provide: MatDialog,
        useValue: mockMatDialog,
      },
    ]
  });
});

// If you want to get data from this spy observable use the following // syntax

apiServiceSpy.createEntity.and.returnValue(of({name: 'dummy data'}))

新查询的更新

是的,您可以传递实际服务返回的数据,例如createEntity. 我的意思是您可以传递满足您标准的测试所需的任何数据。您不应检查 http 请求的 URL 或方法,因为它们不是此服务的一部分。但是在服务中你可以测试是否createEntity()调用了apiservice的方法以及使用了哪些参数。

喜欢

expect(apiServiceSpy.createEntity).toHaveBeenCalled();
OR
// you can get most recent calls to this method
expect(apiServiceSpy.createEntity.calls.mostRecent()).
OR
// you can check the arguments passed to createEntity method as well
expect(apiServiceSpy.createEntity.calls.allArgs())

推荐阅读