Jasmine 角度测试用例返回TypeError:\u this.reCaptchaApi.render不是函数
我已经以6种反应形式实现了ngx验证码。该功能对我来说运行良好,但当我运行单元测试用例时,测试用例失败,并显示以下消息: TypeError:_this.reCaptchaApi.render不是函数 我在两个组件中实现了ngx验证码(可见类型)。对于这两个组件,功能对我来说都很好,但是在单元测试用例运行期间,我遇到了上面提到的错误 我尝试了以下方法: captcha-test.htmlJasmine 角度测试用例返回TypeError:\u this.reCaptchaApi.render不是函数,jasmine,angular5,karma-jasmine,angular-test,Jasmine,Angular5,Karma Jasmine,Angular Test,我已经以6种反应形式实现了ngx验证码。该功能对我来说运行良好,但当我运行单元测试用例时,测试用例失败,并显示以下消息: TypeError:_this.reCaptchaApi.render不是函数 我在两个组件中实现了ngx验证码(可见类型)。对于这两个组件,功能对我来说都很好,但是在单元测试用例运行期间,我遇到了上面提到的错误 我尝试了以下方法: captcha-test.html <ngx-recaptcha2 #captchaElem [siteKey]="captchaSite
<ngx-recaptcha2 #captchaElem [siteKey]="captchaSiteKey"
formControlName="captcha"> </ngx-recaptcha2>
//验证码-test.spec.ts
import { async, ComponentFixture, TestBed } from
"@angular/core/testing";
import { HttpClientModule } from "@angular/common/http";
import { CaptchaTestComponent } from "./captcha-test.component";
import { BrowserAnimationsModule } from "@angular/platform-
browser/animations";
import { RouterTestingModule } from "@angular/router/testing";
import { MatProgressSpinnerModule, MatFormFieldModule, MatInputModule }
from "@angular/material";
import { ReactiveFormsModule, FormBuilder } from "@angular/forms";
import { TestConstants } from "src/app/test/constants";
import { NgxCaptchaModule } from "ngx-captcha";
describe("CaptchaTestComponent", () => {
jasmine.getEnv().allowRespy(true);
let fixture: ComponentFixture<CaptchaTestComponent>;
beforeEach(async(function () {
TestBed.configureTestingModule({
imports: [RouterTestingModule, BrowserAnimationsModule,
ReactiveFormsModule, HttpClientModule, MatProgressSpinnerModule,
MatFormFieldModule, MatInputModule, NgxCaptchaModule],
providers: [FormBuilder
],
declarations: [CaptchaTestComponent]
}).compileComponents();
}));
beforeEach(function () {
fixture = TestBed.createComponent(CaptchaTestComponent);
this.component = fixture.componentInstance;
this.component.captchaExampleForm.controls["captcha"].setValue(TestConstan ts.validCaptcha); //manually set a string data as input data.
fixture.detectChanges();
});
it("should init component properly", function () {
this.component.ngOnInit();
expect(this.component.captchaExampleForm).toBeDefined();
});
it("should return submit as false when we submit the form", async
function () {
const result = await this.component.exapmleFormSubmit();
expect(result).toBeFalsy();
});
});
import{async,ComponentFixture,TestBed}from
“@角度/核心/测试”;
从“@angular/common/http”导入{HttpClientModule};
从“/captcha test.component”导入{CaptchaTestComponent};
从“@angular/platform-
浏览器/动画”;
从“@angular/router/testing”导入{RouterTestingModule}”;
导入{MatProgressSpinnerModule,MatFormFieldModule,MatInputModule}
从“@角度/材料”;
从“@angular/forms”导入{ReactiveFormsModule,FormBuilder}”;
从“src/app/test/constants”导入{TestConstants};
从“ngx验证码”导入{NgxCaptchaModule};
描述(“CaptChatTestComponent”,()=>{
jasmine.getEnv().allowRespy(true);
let夹具:组件夹具;
beforeach(异步(函数(){
TestBed.configureTestingModule({
导入:[RouterTestingModule,BrowserAnimationsModule,
反应窗体模块、HttpClientModule、MatProgressSpinnerModule、,
MatFormFieldModule、MatInputModule、NGxCaptChamModule],
提供者:[表单生成器]
],
声明:[CaptChatTestComponent]
}).compileComponents();
}));
beforeach(函数(){
fixture=TestBed.createComponent(CaptchaTestComponent);
this.component=fixture.componentInstance;
this.component.captcheaexampleform.controls[“captcha”].setValue(TestConstan ts.validCaptcha);//手动将字符串数据设置为输入数据。
fixture.detectChanges();
});
它(“应该正确初始化组件”,函数(){
this.component.ngOnInit();
expect(this.component.captchexampleform).toBeDefined();
});
它(“当我们提交表单时,应该将submit返回为false”),异步
函数(){
const result=wait this.component.exapmleFormSubmit();
expect(result.toBeFalsy();
});
});
我正在使用“ngx验证码”:“^5.0.4”版本和Angular 6。看起来这是一个时间问题。我把你目前发布的内容放到一个文件夹中,以复制你的问题。正如你在StackBlitz中看到的,这两个测试现在都通过了 我对测试套件所做的更改是在第二个
beforeach()
中更改调用fixture.detectChanges()的顺序。在更改之前,它看起来是这样的:
beforeEach(function () {
fixture = TestBed.createComponent(CaptchaTestComponent);
this.component = fixture.componentInstance;
this.component.captchaExampleForm.controls["captcha"].setValue(TestConstants.validCaptcha); //manually set a string data as input data.
fixture.detectChanges();
});
beforeEach(function () {
fixture = TestBed.createComponent(CaptchaTestComponent);
this.component = fixture.componentInstance;
fixture.detectChanges();
this.component.captchaExampleForm.controls["captcha"].setValue(TestConstants.validCaptcha); //manually set a string data as input data.
});
在更改之后,它看起来是这样的:
beforeEach(function () {
fixture = TestBed.createComponent(CaptchaTestComponent);
this.component = fixture.componentInstance;
this.component.captchaExampleForm.controls["captcha"].setValue(TestConstants.validCaptcha); //manually set a string data as input data.
fixture.detectChanges();
});
beforeEach(function () {
fixture = TestBed.createComponent(CaptchaTestComponent);
this.component = fixture.componentInstance;
fixture.detectChanges();
this.component.captchaExampleForm.controls["captcha"].setValue(TestConstants.validCaptcha); //manually set a string data as input data.
});
这之所以重要是因为fixture.detectChanges()
调用ngOnInit()
,并且您在ngOnInit()中设置了表单。如果在设置表单之前尝试使用setValue
修改表单,则该表单将不起作用。鸡和蛋的问题。:)
我希望这会有所帮助。我已经通过覆盖包含ngx-recaptcha2组件的模块解决了这个问题
Recaptcha V2的模拟组件
从“@angular/core”导入{Component,Input,forwardRef};
从“@angular/forms”导入{NG_VALUE_ACCESSOR}”;
从“/control\u value\u accessor.mock”导入{MockControlValueAccessor}”;
@组成部分({
//tslint:禁用下一行:组件选择器
选择器:“ngx-recaptcha2”,
模板:“”,
供应商:[
{
提供:NG_值访问器,
useExisting:forwardRef(()=>MockRecaptchaV2Component),
多:真的
},
]
})
导出类MockRecaptchaV2Component扩展了MockControlValueAccessor{
@Input()siteKey:字符串;
}
Recaptcha正在使用formControlName,因此我们需要以下模拟类
从“@angular/forms”导入{ControlValueAccessor};
导出类MockControlValueAccessor实现ControlValueAccessor{
writeValue(对象:任意):无效{
}
注册变更(fn:任何):无效{
}
注册人(fn:任何):无效{
}
setDisabledState?(isDisabled:boolean):无效{
}
}
我们现在需要使用以下代码覆盖NgxCaptchaModule模块
beforeach(异步(函数)(){
TestBed.configureTestingModule({
导入:[浏览动画模块,反应表单模块,ngxcaptchamule],
声明:[SignupComponent,MockRecaptchaV2Component],
}).overrideModule(NgxCaptchaModule{
删除:{
//需要SignupComponent,因为ReCaptcha2Component用作SignupComponent中的子组件
声明:[SignupComponent,ReCaptcha2Component],
导出:[注册组件,重述组件]
}
}).compileComponents();
}));
在我看来,这是迄今为止最干净的解决方案,只需在导入中使用ng mocks包并模拟NgxCaptchaModule即可
beforeach(异步(()=>{
TestBed.configureTestingModule({
进口:[
//其他进口
模拟模块(NgxCaptchaModule),
],
声明:[
注册组件
]
}).compileComponents();
}));
Protip:模拟所有组件和模块。使用此策略将增加组件中测试的隔离度请包含您尝试的整个.spec文件。我在问题部分添加了.spec文件。多谢各位@dmcgrandlethis不起作用,我们仍然会得到相同的渲染错误,但有时它会通过,所以在执行测试时是否存在任何竞争条件的可能性?很有趣。在这次闪电战中,它似乎一直在通过。也许您可以将StackBlitz转移到您自己的帐户,并使用组件和模板中的所有数据进行更新。这段代码中可能有些东西