Ang*_*arM 1 testing typescript angular cypress
技术堆栈: Angular v15 和 Cypress v12。
我正在测试的示例组件:
import { Component } from '@angular/core';
import { UserHttp } from '../../services';
@Component({
selector: 'example-view',
templateUrl: './example.component.html',
})
export class ExampleComponent {
constructor(
private userHttp: UserHttp,
) { }
}
Run Code Online (Sandbox Code Playgroud)
我的示例组件测试
import { HttpClientModule } from '@angular/common/http';
import { ExampleComponent } from './example.component';
import { UserHttp } from '../../services';
describe('Example component', () => {
beforeEach(() => {
cy.mount(ExampleComponent, {
providers: [UserHttp],
imports: [HttpClientModule]
});
});
it('should display default title', () => {
cy.get('h2').should('exist');
});
});
Run Code Online (Sandbox Code Playgroud)
我正在注入的 UserHttp 服务:
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
@Injectable()
export class UserHttp {
test(): Observable<any> {
return of({});
}
}
Run Code Online (Sandbox Code Playgroud)
当前状态:
如果我将导入保留为:import { Http } from '..'; ,上述测试将会失败。
但如果我将其更改为这样,它就可以工作:import { Http } from './http';
我将其设置为 import { Http } from '..' 的原因是因为我使用索引文件来导出所有服务,如下所示:
// index.ts: services:
import { UserHttp } from './http/user.http';
import { StorageService } from './storage.service';
export * from './http/user.http';
export * from './storage.service';
export const SERVICES = [
StorageService,
UserHttp,
];
Run Code Online (Sandbox Code Playgroud)
我的存储服务:
import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
@Injectable()
export class StorageService {
baseKey: string = environment.baseStorageKey;
constructor() {}
setLocalStorage(key: string, value: any): void {
this.removeLocalStorage(key);
localStorage.setItem(`${this.baseKey}${key}`, JSON.stringify(value));
}
getLocalStorage(key: string): any {
const item = localStorage.getItem(`${this.baseKey}${key}`);
return item !== null ? JSON.parse(item) : '';
}
removeLocalStorage(key: string): void {
localStorage.removeItem(`${this.baseKey}${key}`);
}
removeBatchLocalStorage(keys: string[]): void {
keys.forEach((key: string) => {
localStorage.removeItem(`${this.baseKey}${key}`);
});
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的赛普拉斯配置:
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
chromeWebSecurity: false,
screenshotsFolder: "cypress/snapshots",
trashAssetsBeforeRuns: true,
viewportWidth: 1400,
viewportHeight: 1200,
video: false,
env: {
local: "http://localhost:4200/",
staging: "https://hidden.co.uk/",
user: {
email: "hidden",
password: "hidden",
},
},
component: {
devServer: {
framework: "angular",
bundler: "webpack",
},
specPattern: "**/*.cy.ts",
},
});
Run Code Online (Sandbox Code Playgroud)
有没有办法在 tsconfig 或 cypress 配置中设置 index.ts 文件方法?
我得到的当前错误:
TypeError
The following error originated from your test code, not from Cypress.
> Cannot read properties of undefined (reading 'StorageService')
When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.
Cypress could not associate this error to any specific test.
We dynamically generated a new test to display this failure.
Run Code Online (Sandbox Code Playgroud)
我的 TS 配置文件:
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": false,
"strictPropertyInitialization": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2020",
"module": "es2020",
"skipLibCheck": true,
"allowJs": true,
"types": [
"node"
],
"lib": [
"es2018",
"dom"
],
"paths": {
"@app/*": ["src/app/*"],
"@services/*": ["src/app/services/*"]
}
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": false,
"strictInputAccessModifiers": false,
"strictTemplates": false
}
}
Run Code Online (Sandbox Code Playgroud)
我的 http.ts 服务器由 userHttp 服务扩展:
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../../environments/environment';
@Injectable()
export abstract class Http {
protected baseUrl = environment.baseUrl;
protected headers: HttpHeaders;
constructor(public httpClient: HttpClient) {}
protected get<T>(path: string, options: any = {}, noBaseUrl = false): Observable<T> {
const url: string = this.createUrlString(path, noBaseUrl);
const params: HttpParams = this.getHttpParams(options.queryString);
return this.httpClient.get<T>(url, { params });
}
protected post<T>(path: string, data = {}, noBaseUrl = false): Observable<T> {
const url: string = this.createUrlString(path, noBaseUrl);
const options = { headers: this.headers };
return this.httpClient.post<T>(url, { ...data, lang: 'uk' }, options);
}
protected createUrlString(resourcePath: string, noBaseUrl: boolean): string {
return noBaseUrl ? `${resourcePath}` : `${this.baseUrl}${resourcePath}`;
}
protected getHttpParams(params: any): HttpParams {
let httpParams: HttpParams = new HttpParams();
if (params) {
for (const prop in params) {
if (params.hasOwnProperty(prop)) {
const parameterValue: string = params[prop].toString();
httpParams = httpParams.append(prop, parameterValue);
}
}
}
return httpParams;
}
}
Run Code Online (Sandbox Code Playgroud)
图形界面错误信息
如果我正确地重现了错误(看起来是这样,因为对您提到的导入的更改修复了它),那么错误是
ReferenceError
以下错误源自您的测试代码,而不是来自 Cypress。初始化前无法访问“UserHttp”
您可以通过服务索引导入来修复组件中的问题UserHttp,而不是直接从其实现中导入。
示例组件
import { Component } from '@angular/core';
// import { UserHttp } from '../../services/http/user.http';
import { UserHttp } from '../../services';
@Component({
selector: 'example-view',
templateUrl: './example.component.html',
})
export class ExampleComponent {
constructor(
private userHttp: UserHttp,
) { }
}
Run Code Online (Sandbox Code Playgroud)
我认为原因是它UserHttp依赖于services/index但该索引没有被测试直接引用,因此没有得到遵守。
错误消息确实看起来令人困惑,它应该是抱怨Http.ts而不是UserHttp.ts。
| 归档时间: |
|
| 查看次数: |
478 次 |
| 最近记录: |