Javascript 角度7测试公共方法依赖于私人方法
我使用angular 7.1和Jasmine来测试我的组件。我正试着写一些测试,但这个似乎对我来说太多了 我尝试测试的简化类:Javascript 角度7测试公共方法依赖于私人方法,javascript,angular,jasmine,Javascript,Angular,Jasmine,我使用angular 7.1和Jasmine来测试我的组件。我正试着写一些测试,但这个似乎对我来说太多了 我尝试测试的简化类: import { HttpClient } from '@angular/common/http'; @Component({ selector: 'a', templateUrl: './a.html', styleUrls: ['./a.scss'] } export class A implements OnInit { constructor(
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'a',
templateUrl: './a.html',
styleUrls: ['./a.scss']
}
export class A implements OnInit {
constructor(private http: HttpClient) {}
private privateState: State;
public publicState: State2;
ngOnInit() {
this.http.get(this.GetUrl()).subscribe((x) => {
this.privateState = x['whatever'];
});
}
private hiddenComplexFunction() {
this.publicState = this.privateState.something;
}
public testedFunction() {
//someComplex Code
this.hiddenComplexFunction();
}
}
我所尝试的:
- 我试图设置私有变量,如
,但没有成功A.['privateState']
- 我尝试使用SpyOn http get,但也遇到了同样的问题,即必须设置私有属性
- 我试图使用HttpClientTestingModule,但我遇到了与前一点相同的问题
- 最后,我尝试使privateState受到保护,并通过以下方式进行测试:
import { HttpClientTestingModule } from '@angular/common/http/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; class AMock extends A { ngOnInit() { //privateState is now protected this.privateState = mockedState; } } describe('A', () => { let component: AMock; let fixture: ComponentFixture<AMock>; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], declarations: [AMock] }) .compileComponents().catch(); })); beforeEach(() => { fixture = TestBed.createComponent(AMock); component = fixture.componentInstance; }); it('testedFunction should set up public state correctly', () => { component.testedFunction(); expect(component.publicState).toEqual(mockedState.something); });
运行从'@angular/common/http/testing'导入{HttpClientTestingModule}; 从“@angular/core/testing”导入{async,ComponentFixture,TestBed}; 类AMock扩展了{ 恩戈尼尼特(){ //私有国家现在受到保护 this.privateState=mockedState; } } 描述('A',()=>{ let组件:AMock; let夹具:组件夹具; beforeach(异步(()=>{ TestBed.configureTestingModule({ 导入:[HttpClientTestingModule], 声明:[阿莫克] }) .compileComponents().catch(); })); 在每个之前(()=>{ fixture=TestBed.createComponent(AMock); 组件=fixture.componentInstance; }); 它('testedFunction应该正确设置公共状态',()=>{ testedFunction(); expect(component.publicState).toEqual(mockedState.something); });
命令后,由于无法读取未定义的属性“testedFunction”,最后一点不起作用,返回错误ng test
我不知道哪种方法是正确的测试方法。我知道我可以将
hiddenComplexFunction
公开,我的所有问题都会消失,而且我不喜欢因为测试而必须更改访问修饰符(从private改为protected,就像在模拟示例中一样,这对我来说似乎完全错误).你的问题有很多,所以我将从我能很容易看到的东西开始
我们可以从您的核心组件代码开始。在testedFunction()中,调用this.hiddenComplexFunction()。您需要该函数的实例版本,因此需要将“this.”添加到其中。这非常合适,而且您也不想直接测试私有函数/私有属性
接下来,我猜你想要这个代码
this.state = x['whatever'];
设置您的私有状态,而不是状态
this.privateState = x['whatever'];
接下来,你不需要用你的AMock类来模拟A,测试装配会帮你做到这一点。尝试下面的方法作为开始。我这里没有的是状态代码。我真正做的就是去掉你的AMock,用实际的组件替换它,并构建一个测试状态(我可能会补充说,这个状态构建得很糟糕。哈!).我处理下面的HTTP数据,通过查看您的代码,我猜这些数据与您的状态有关
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { A } from './zing.component'; // this should point to your component
// get rid of this, not needed
// class AMock extends A {
// ngOnInit() {
// //privateState is now protected
// let privateState = mockedState;
// }
// }
describe('A', () => {
let component: A; // changed from AMock to A
let fixture: ComponentFixture<A>; // changed from AMock to A
let mockedState = {something: 'yelp'}; // build your expected state here
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [A] // changed from AMock to A
})
.compileComponents().catch();
}));
beforeEach(() => {
fixture = TestBed.createComponent(A); // changed from AMock to A
component = fixture.componentInstance;
});
it('testedFunction should set up public state correctly', () => {
component.testedFunction();
expect(component.publicState).toEqual(mockedState.something);
});
});
在每次会议前—
backend = TestBed.get(HttpTestingController);
在你的IT声明中-
backend.expectOne(expectedURL).flush(mockedState);
backend.verify();
让我们知道这对你有多大帮助,如果它有用或者你有其他错误。这是一个纯类,还是一个组件?你没有@component decorator,但正在尝试使用onInit,并尝试在测试中将其实例化为一个组件fixture。如果它是一个类,那将是一个不同于组件的答案。it是一个组件,我将添加decorator这似乎解决了我的大多数问题,有没有办法存根任何地址,而不必在expectedURL中指定一个地址?我想使用
backend.expectOne(()=>true).flush(mockedState);
不是测试请求的正确方法,您可以尝试使用-const backendRequest=backend.expectOne((请求:HttpRequest,在使用HttpClientTestingModule头设置第二个规范(我的站点)下)还有,对代码进行优化-从ngOnInit中删除功能。生命周期方法很难测试。将该代码添加到getData()中然后,您可以轻松地测试该方法中数据的检索,并能够模拟该方法来测试依赖于该方法的其他代码。
backend.expectOne(expectedURL).flush(mockedState);
backend.verify();