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

Posted

技术标签:

【中文标题】模拟服务以调用本地 json-server 而不是远程端点 - 测试语法? (角度 2)【英文标题】:Mocking a service to call local json-server instead of remote endpoint - test syntax? (Angular 2) 【发布时间】:2017-01-23 14:44:57 【问题描述】:

我正在尝试编写一个单元测试,以确定我的 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-server 的方法替换 service 方法。

据我所知,在 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】:

如果你在模拟服务,你不应该使用Http。只需返回您自己的承诺,无需与Http 交互。

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

使用Http 服务,您将进行 XHR 调用,而您不想在测试期间这样做。对于 mocks,我们想让它尽可能简单,因为我们希望它尽可能少地影响测试中的组件。

Http在测试过程中的另一个问题是它依赖于平台浏览器,在测试环境中是不可用的。这并不意味着我们不能使用它。我们只需要使用 Angular 提供的帮助类进行测试。

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

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

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

另请参阅:

Documentation for Promise,如果您不熟悉创建自己的 Promise。

【讨论】:

谢谢...我猜我不会走那条路了:)

以上是关于模拟服务以调用本地 json-server 而不是远程端点 - 测试语法? (角度 2)的主要内容,如果未能解决你的问题,请参考以下文章

使用json-server与Mockjs搭建模拟服务

React之模拟数据库json-server 2019-01-26

JSON-Server:使用参数模拟端点

插件---- json-server基本使用

json-server30秒无代码搭建一个完整的REST API服务-基础入门

Json-server GET 请求不断触发