我有一个使用Authorize.nets Accept.js SDK完成付款的角度组件。我不想加载Accept.js脚本,除非用户在付款界面上,所以我通过我在组件中调用onInit
的方法将脚本添加到页面中。
some.component.ts
ngOnInit {
this.addAcceptJsScript();
}
private addAcceptJsScript(): void {
const element = document.createElement('script');
element.src = environment.acceptJsUrl;
element.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(element);
}
some.service.ts
declare var Accept: any;
@Injectable()
export class SomeService {
private sendPaymentToAuthNet(paymentPayload): void {
Accept.dispatchData(paymentPayload, this.handleAuthNetResponse);
}
}
这适用于用户,因为脚本在DOM中加载,并且在组件调用使用Accept
API的服务时可用
但是,在使用API的服务中我的单元测试没有任何对Accept
的引用,所以当它尝试测试我调用Accept.dispatchData(...)
测试错误的代码行时说'参考错误:未定义接受“。
我尝试了各种模拟接受的方法,但没有一种方法可以用于测试。我如何将我的模拟Accept
注入服务中,以便在代码尝试使用它时声明它?
答案 0 :(得分:1)
测试问题通常表明应用程序设计存在缺陷。
document
最好应该是一个提供者,因为它应该在某个时候被嘲笑以避免将脚本元素添加到真正的DOM中。已经有DOCUMENT
提供程序可以注入组件而不是document
全局。并在试验台上嘲笑:
{
provide: DOCUMENT,
useValue: jasmine.createSpyObj('document', ['createElement', 'getElementsByTagName'])
}
createElement
和getElementsByTagName
茉莉花间谍应配置为返回正确的模拟对象。
Accept
应该成为提供者。该值可以分配到window['Accept']
,如this answer所示,并在试验台中进行模拟。
答案 1 :(得分:0)
我只需要在karma.config中的files文件对象中包含Accept.js CDN的路径
files: [
{ pattern: './src/test.ts', watched: false },
{ pattern: './node_modules/@angular/material/prebuilt-themes/indigo-pink.css', included: true, watched: true },
{ pattern: 'https://jstest.authorize.net/v1/Accept.js', nonull: true }
]