模拟服务调用本地json服务器而不是远程端点 - 测试语法? (Angular 2)

时间:2016-09-15 14:13:47

标签: angular mocking jasmine karma-runner json-server

我正在尝试编写单元测试,以确定在返回promise的服务调用之后填充了我的angular 2组件上的属性。

我的组件包含一个方法:

getListItems() {
  this.employeeService.loadEmployees().then(res => {
    this._employees = res['Employees'];
    this.ref.markForCheck();
   });
};

调用服务上的方法:

@Injectable()
export class EmployeeService {

  constructor(
    public http: Http
  ) { }
		
  public loadEmployees(): Promise<any> {
    return this.http.get('employees.json')
      .map((res: Response) => res.json())
      .toPromise();
  }
}

从本地json文件中获取内容(代替创建远程端点)。这很好用,但我想用一个调用本地json服务器的服务方法替换服务方法。

据我所知,当Karma测试运行时,我已经正确地启动/关闭了json-server - 我可以使用Postman在测试运行时成功执行GET请求。

因此,我想用模拟替换我的服务:

class MockEmployeeService {
  headers: Headers;

  constructor(private http: Http) {
    this.headers = new Headers({ 'Content-Type': 'application/json' });
  }

  public loadEmployees() {
    return this.http.get('http://localhost:3004/getEmployees',
      {headers: this.headers, body: '' })
	    .map((res: Response) => res.json());
	}
}

我按如下方式设置了单元测试:

describe('ListComponent', () => {

  let fixture;
  let component;
  let employeeService;

  beforeEach( async(() => {

	TestBed.configureTestingModule({
	  imports: [
		HttpModule
	  ],
	  declarations: [
		ListComponent
	  ],
	  providers: [
	    {provide: EmployeeService, useClass: MockEmployeeService}
	  ]
    })
    .compileComponents();
  }));

  beforeEach(() => {

	fixture = TestBed.createComponent(ListComponent);
	component = fixture.componentInstance;

	employeeService = fixture.debugElement.injector
      .get(EmployeeService);
	});

  it('should retrieve test values from json-server (async)',
    async(() => {
	  fixture.detectChanges();
	  component.getListItems();
	  fixture.whenStable.then(() => {
		expect(component._employees).toBeDefined();
	  });
  }));
})

所以(我认为)我正在调用应该调用服务的组件上的方法,该方法应该由MockEmployeeService替换。我收到以下Karma错误:

× should retrieve test values from json-server (async)
  PhantomJS 2.1.1 (Windows 7 0.0.0)
Failed: Can't resolve all parameters for MockEmployeeService: (?).

在这一点上,我几乎处于我的知识界限,而且我很难找到更新的TestBed使用测试的在线资源。是否有人能够在这里看到任何东西?

1 个答案:

答案 0 :(得分:0)

如果您正在嘲笑该服务,则不应使用Http。只需返回您自己的承诺,而无需与Http进行互动。

class MockEmployeeService {
  public loadEmployees() {
    return Promise.resolve({some:'object'});
  }
}

使用Http服务,您将进行XHR通话,这是您在测试期间不想做的。对于模拟,我们希望尽可能简化,因为我们希望它尽可能地影响测试中的组件。

测试期间Http的另一个问题是它依赖于平台浏览器,而测试环境中没有该浏览器。这并不意味着我们无法使用它。我们只需要使用Angular提供的帮助类进行测试。

我们讨论了模拟测试组件的服务,但是如果您还想测试服务,则需要使用一些Angular测试助手类Http自己创建MockBackend提供程序。

TestBed.configureTestingModule({
  providers: [
    {
      provide: Http, useFactory: (backend, options) => {
        return new Http(backend, options);
      },
      deps: [MockBackend, BaseRequestOptions]
    },
    MockBackend,
    BaseRequestOptions
  ]
});

使用MockBackend,我们可以订阅连接和模拟响应。有关完整示例,请参阅this post

另见: