Angular 在单元测试覆盖率中包含组件模板
使用Angular 4可以测试组件的模板,例如检查单击按钮是否触发预期的方法等Angular 在单元测试覆盖率中包含组件模板,angular,jasmine,karma-runner,code-coverage,istanbul,Angular,Jasmine,Karma Runner,Code Coverage,Istanbul,使用Angular 4可以测试组件的模板,例如检查单击按钮是否触发预期的方法等 但是,如何将模板包括在测试覆盖范围内呢?默认情况下,它们不是(使用带有Karma+Jasmine+Istanbul的Angular CLI测试)。在我看来,您只能在单击时测试调用的函数,因为您不需要验证单击Angular是否会调用此函数 但是如果你想用任何方法测试它,你可以这样做 import { TestBed, async, ComponentFixture } from '@angular/core/testi
但是,如何将模板包括在测试覆盖范围内呢?默认情况下,它们不是(使用带有Karma+Jasmine+Istanbul的Angular CLI测试)。在我看来,您只能在单击时测试调用的函数,因为您不需要验证单击Angular是否会调用此函数 但是如果你想用任何方法测试它,你可以这样做
import { TestBed, async, ComponentFixture } from '@angular/core/testing';
describe('', () => {
let fixture: ComponentFixture<TestComponent>;
let component: TestComponent;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ ],
declarations: [ TestComponent ],
providers: [ ]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
});
}));
});
it('should click on button', async(() => {
spyOn(component, 'onEditButtonClick');
let button = fixture.debugElement.nativeElement.querySelector('button');
button.click();
// here you can test you code or just check that your function have been called like in the example bellow
fixture.whenStable().then(() => {
expect(component.onEditButtonClick).toHaveBeenCalled();
});
}));
从'@angular/core/testing'导入{TestBed,async,ComponentFixture};
描述(“”,()=>{
let夹具:组件夹具;
let组件:TestComponent;
beforeach(异步(()=>{
TestBed.configureTestingModule({
进口:[],
声明:[TestComponent],
提供者:[]
}).compileComponents()。然后(()=>{
fixture=TestBed.createComponent(TestComponent);
组件=fixture.componentInstance;
});
}));
});
它('应该点击按钮'),异步(()=>{
spyOn(组件“onEditButtonClick”);
let button=fixture.debugElement.nativeElement.querySelector('button');
按钮。单击();
//在这里,您可以测试您的代码,或者检查您的函数是否已被调用,如下面的示例所示
fixture.whenStable()然后(()=>{
expect(component.onEditButtonClick).toHaveBeenCalled();
});
}));
您的意思是想测试模板的实际表示形式吗?然后,你必须完全转向玩笑,而不是因果报应/茉莉花组合。使用jest,您可以在测试中生成模板快照,这些快照与组件一起推送,并在CI测试中检查
例如,假设您有一个main.component,它在SessionService未就绪时显示加载程序,然后在完成时显示路由内容的路由器出口。jest快照看起来有点像这样:
exports[`MainComponent renders: default state 1`] = `
<main
isReady$={[Function BehaviorSubject]}
sessionService={[Function Object]}
>
<loader-line
ng-reflect-active="true"
/>
</main>
`;
exports[`MainComponent session storage is ready renders 1`] = `
<main
isReady$={[Function BehaviorSubject]}
sessionService={[Function Object]}
>
<main>
<router-outlet />
</main>
</main>
`;
exports[`MainComponent呈现:默认状态1`]=`
`;
导出[`MainComponent会话存储已就绪渲染1`]=`
`;
测试代码如下所示:
describe('MainComponent', () => {
let fixture: ComponentFixture<MainComponent>;
const isReady$ = new BehaviorSubject(false);
const mockSessionStorage = Mock.all<SessionService>();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MainComponent, MockComponents(LoaderLineComponent)],
imports: [RouterTestingModule],
providers: [mockWith(SessionService, mockSessionStorage)],
})
.compileComponents();
}));
afterAll(() => {
isReady$.complete();
});
beforeEach(() => {
Mock.extend(mockSessionStorage).with({isReady$});
fixture = TestBed.createComponent(MainComponent);
detectChanges(fixture);
});
it(`creates instance`, () => expect(fixture.componentInstance).toBeTruthy());
it(`renders`, () => expect(fixture).toMatchSnapshot(`default state`));
describe(`session storage is ready`, () => {
beforeEach(() => {
isReady$.next(true);
detectChanges(fixture);
});
it(`renders`, () => expect(fixture).toMatchSnapshot());
});
});
description('MainComponent',()=>{
let夹具:组件夹具;
const isReady$=新行为主体(false);
const mockSessionStorage=Mock.all();
beforeach(异步(()=>{
TestBed.configureTestingModule({
声明:[MainComponent,MockComponents(LoaderLineComponent)],
导入:[RouterTestingModule],
提供者:[mockWith(会话服务,mockSessionStorage)],
})
.compileComponents();
}));
毕竟(()=>{
isReady$.complete();
});
在每个之前(()=>{
extend(mockSessionStorage).with({isReady$});
fixture=TestBed.createComponent(主组件);
检测变化(夹具);
});
它(`creates instance`,()=>expect(fixture.componentInstance.toBeTruthy());
它(`renders`,()=>expect(fixture.toMatchSnapshot(`defaultstate`));
描述(`session storage is ready`,()=>{
在每个之前(()=>{
isReady$.next(true);
检测变化(夹具);
});
它(`renders`,()=>expect(fixture.toMatchSnapshot());
});
});
就这样,不再查询规范文件代码中的
或
,只需查看快照即可
注意:我也在使用ng mocks、ts mockry和一些自己的util函数,但是您要寻找的主要内容是
expect(fixture).toMatchSnapshot()
行,它们是本机的笑话。在我看来,您应该重新思考您想要测试什么以及如何测试。您可以测试是否从组件内部触发了某些内容(单元测试),例如,如果我调用此函数,则此属性会更改值
导出类页面{
列表内容:字符串[]=[];
addStuff:(item:string)=>this.listOfSomething.push(item);
}
在这里,您可以测试某物的列表是否随时间而变化
若要知道某个按钮是否从模板中的按钮执行此操作,则可能会出现这种情况
{{item}
添加内容
在这种情况下,如果单击按钮,您希望看到屏幕上的元素数量发生变化。基本上,您是在间接地检查addStuff
和list of something
,但仍然在检查它们
--
总之,您需要将测试分为单元测试和e2e测试。
Jasmine更适合于单元测试。你可能会找到一种方法,但不值得花时间
下面您可以看到登录页面(e2e)所需的不同方法
从“量角器”导入{browser,by,element};
导出常量testData={
用户名:1231232,
密码:“pass1234”
};
导出类登录页{
//////////////////////////////////////////////////////////////////////////////////////////
//导航//////
导航(){
返回browser.get('/login');
}
快速登录(){
这是navigateTo();
this.setMobileNumber(testData.userName);
this.setPassword(testData.password);
这是doLogin();
}
//////////////////////////////////////////////////////////////////////////////////////////
//选择器/////
getLoginButton(){
返回元素(by.buttonText(“登录”);
}
//////////////////////////////////////////////////////////////////////////////////////////
//getText///////
GetSelectedMobileNumber前缀(){
返回元素(by.deepCss('section form.mat select.value output')).getText();
}
getErrorMessage(){
return元素(by.deepCss('snack-bar-container-simple snack-bar span')).getText();
}
//////////////////////////////////////////////////////////////////////////////////////////
//发送键//////
setMobileNumber(电话号码:number){
返回元素(by.css('[formControlName=phoneNumber]')).sendKeys(phoneNumber);
}
设置密码(密码:字符串){
返回元素(按.css('[formControlName=pass