【问题标题】:Mocking http calls with AuthHttp in AngularJS 2在 AngularJS 2 中使用 AuthHttp 模拟 http 调用
【发布时间】:2017-02-22 10:05:01
【问题描述】:

在我的 Angular 2.0.0 应用程序中,我试图在使用 AuthHttp 而不是 Http 的服务中模拟 HTTP 调用。

@Injectable()
export class FundingPlanService {
  constructor(private http: AuthHttp);

  getFundingPlans(): Observable<FundingPlan[]> {
    return this.http.get('http://localhost:8080/api/fundingplans')
      .map((response: Response) => {
        return response.json();
      }).map((json: any) => {
        // some logic here
        return fundingPlans;
      });
  }
}

在测试中,我乱七八糟地在网上找到了一些零零碎碎的东西,像这样:

describe('Service: FundingPlan', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        FundingPlanService,
        MockBackend,
        BaseRequestOptions,
        {
            provide: Http,
            useFactory: (backend, options) => new Http(backend, options),
            deps: [MockBackend, BaseRequestOptions]
        },
        {
            provide: AuthHttp,
            useFactory: (http) => new AuthHttp(new AuthConfig(), http),
            deps: [Http]
        }
      ]
    });
  });

  it('should ...', inject([FundingPlanService, MockBackend], fakeAsync((service: FundingPlanService, backend: MockBackend) => {
    backend.connections.subscribe((connection: MockConnection) => {
      expect(false).toBe(true);
      expect(connection.request.method).toBe(RequestMethod.Get);
      expect(connection.request.url).toBe('http://localhost:8080/api/fundingplans');
    });

    let fundingPlans = service.getFundingPlans();
  })));
});

Http 使用 MockBackendAuthHttp 使用带有模拟后端的 Http

LOG: '*** const ', AuthHttp{http: Http{_backend: MockBackend{connectionsArray: ...

expect 语句永远不会执行。可以肯定的是,我添加了expect(false).toBe(true);,但测试以SUCCESS 结束。

我错过了什么?

【问题讨论】:

    标签: unit-testing angular mocking


    【解决方案1】:

    第一个问题:

    您缺少请求的异步行为,有多种方法可以实现异步测试:

    通过将测试包装在 async 区域中:

    it('should ...', async(inject([FundingPlanService, MockBackend], (service: FundingPlanService, backend: MockBackend) => {
        ... 
        ...
        }));
    

    使用done()回调参数:

    it('should ...', (done) => {inject([FundingPlanService, MockBackend], (service: FundingPlanService, backend: MockBackend) => {
          ...
          ...
          done();
        }});
    

    您使用了fakeAsync,但这是用于假异步计时器,这里您明确使用异步调用,因此您应该使用这两种方法之一。

    第二个问题:

    您订阅的连接后端从未被调用,因为您从未调用http,订阅连接后端应用于指定您希望在模型中获得哪个响应:

    it('should ...', async(inject([FundingPlanService, MockBackend], (service: FundingPlanService, backend: MockBackend) => {
        backend.connections.subscribe((connection: MockConnection) => {
            const options: ResponseOptions = new ResponseOptions(
                    {
                        body   : "Your body as string",
                        headers: new Headers(),
                        status : 200
                    }
                );
                conn.mockRespond(new Response(options));
        });
        //And then your expectations
        expect(service.getFundingPlans()).toBe(dunnoWhat);
    }));
    

    【讨论】:

    • 感谢您提供有关各种asyncdone 回调和fakeAsync 的补充信息。后者很容易被混淆。
    • 第一个解决方案没有经过'false==true'。第二个解决方案产生Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 2015-01-02
    • 2017-07-13
    • 1970-01-01
    相关资源
    最近更新 更多