Angular 如何在没有测试床的情况下模拟非类、非导出变量

Angular 如何在没有测试床的情况下模拟非类、非导出变量,angular,unit-testing,jestjs,Angular,Unit Testing,Jestjs,我需要测试更多的服务。类测试,而不是组件测试,因此我不能使用Testbed,但必须使用let service=new MyService模拟它。但是,这些服务中的一小部分使用既不是类变量也不是导出的硬编码对象 如何访问这些变量并使其可供构造函数使用 我的服务 import { Injectable, Inject } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; impo

我需要测试更多的服务。类测试,而不是组件测试,因此我不能使用Testbed,但必须使用
let service=new MyService
模拟它。但是,这些服务中的一小部分使用既不是类变量也不是导出的硬编码对象

如何访问这些变量并使其可供构造函数使用

我的服务

import { Injectable, Inject } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { ServicedItem } from '../../models/serviced-item.model';

const headers = new HttpHeaders() // <--- How to mock this???
.append('appended stuff here');

export class MyService {
  constructor(
    private readonly httpClient: HttpClient,
    @Inject('env') private env,
  ) {}

  public getServicedItem(id: string): Observable<ServicedItem> {
    return this.httpClient.get<ServicedItem>(
      `${this.env.webApiBaseUrl}servicedItem/${id}`, 
      { headers }
    );
  }
}
实际上,我得到了一个TypeError:无法读取标题上未定义的属性“append”。我一直在寻找这样做的方法。。。让我们说从远到久。但我找到的所有教程要么采用测试床,要么选择类,或者至少导出变量。但一定有办法做到这一点,对吗

然后抛出错误:

● Test suite failed to run 
TypeError: Cannot read property 'append' of undefined 

4 | import { ServicedItem } from '../../models/serviced-item.model'; 
5 | > 
6 | const headers = new HttpHeaders() 
  |                  ^ 
7 | .append('Content-Type', 'application/json') 

编辑:


在某些输入之后添加精确错误块。

您遇到的问题是由

jest.mock('@angular/common/http');
在测试中。尝试删除它,或正确模拟其导出

从'@angular/common/http'导入{HttpHeaders};
从'rxjs'导入{of};
从“/my.service”导入{MyService};
描述('MyService',()=>{
让服务:MyService;
const webApiBaseUrl='mocky yes';
const env={webApiBaseUrl}如有;
const id='THE_id';
const testPayload='在此处插入正确的字符串';
description('类:模拟后端测试',()=>{
constHttpClient:any={get:jest.fn()};
在每个之前(()=>{
服务=新的MyService(httpClient,env);
});
测试('应创建',()=>{
expect(service.toBeTruthy();
});
description('方法:getServicedItem',()=>{
test('应返回servicedItem',async()=>{
httpClient.get.mockImplementationOnce(()=>of(testPayload));
const res=wait service.getServicedItem(id).toPromise();
期望(httpClient.get).已被调用(
`${webApiBaseUrl}servicedItem/${id}`,
{
标题:jasmine.any(HttpHeaders),
},
);
expect(res).toBe(testPayload);
});
});
});
});
从'@angular/common/http'导入{HttpClient,HttpHeaders};
从“@angular/core”导入{Inject};
从“rxjs”导入{Observable};

const headers=new HttpHeaders()//我认为问题不在于断言。问题是,测试根本无法运行,因为在没有访问标头的情况下,服务无法正确构造。服务可以访问
标头,因为它们在同一范围内。至少它的意图是这样的:)您能再次检查导致错误的行是否属于
.append('added stuff here')
● 测试套件无法运行TypeError:无法从“../../models/serviced item.model”读取未定义的4 | import{ServicedItem}的属性“append”;5 |>6 | const headers=new HttpHeaders()| ^7 |。append('Content-Type','application/json')8 |。append('Access-Control-Allow-headers','Content-Type')9 |。append('Access-Control-Allow-Methods','GET')``这就是它失败的地方。不知何故,标题是未定义的,这就是为什么我问如何访问它。嗯。。。非常有趣。。。你用什么?听起来进口商品已经被嘲笑了。今天晚些时候我将尝试使用您的代码。对于Angular版本,您会使用吗?@Angular devkit/core:“10.0.4”,模拟是一个ts笑话(^25.0.0)模拟。我一到家就得查一下你的链接。耶,在雪中行走不要嘲笑它-它是实现的一部分,测试是否发出了正确的请求。这就是问题所在,我不能说它甚至没有构造服务。所有的东西都在尖叫——要么是一个非常愚蠢的打字错误,要么是类似的错误(相信我,我一次又一次地检查了它),要么是一些与测试本身无关的奇怪的东西。我只是找不到一个开始来解释这件事。从错误来看,第6行末尾似乎有一个错误的管道
|
,请确保您给出的是一个实际重现问题的管道。啊,很抱歉,管道是从终端复制的。因为您已经模拟了整个
@angular/common/http
HttpHeaders
没有有效的实现。“类测试,而不是组件测试,因此我不能使用测试床”-您仍然可以使用测试床来测试这样的服务类,请参见例如。
● Test suite failed to run 
TypeError: Cannot read property 'append' of undefined 

4 | import { ServicedItem } from '../../models/serviced-item.model'; 
5 | > 
6 | const headers = new HttpHeaders() 
  |                  ^ 
7 | .append('Content-Type', 'application/json')