Angular Accept.js打破单元测试'参考错误:未定义接受'

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Angular Accept.js打破单元测试'参考错误:未定义接受'相关的知识,希望对你有一定的参考价值。

我有一个角度组件,使用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注入服务,以便在代码尝试使用它时声明它?

答案

测试问题通常表明应用程序设计存在缺陷。

document最好应该是一个提供者,因为它应该在某些时候被嘲笑以避免将脚本元素添加到真正的DOM中。已经有DOCUMENT提供者可以注入组件而不是document global。并在试验台上嘲笑:

{
  provide: DOCUMENT,
  useValue: jasmine.createSpyObj('document', ['createElement', 'getElementsByTagName'])
}

其中createElementgetElementsByTagName茉莉花间谍应配置为返回适当的模拟对象。

Accept也应该成为可测试性原因的提供者。该值可以分配给window['Accept'],如this answer所示,并在试验台中进行模拟。

另一答案

我只需要在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 }
]

以上是关于Angular Accept.js打破单元测试'参考错误:未定义接受'的主要内容,如果未能解决你的问题,请参考以下文章

Angular 4 单元测试(TestBed)非常慢

Angular:单元测试路由:预期 '' 是 '/route'

Angular - 组件中订阅功能的单元测试

angular2 使用主机组件进行单元测试

Angular 2 单元测试组件,模拟 ContentChildren

Angular 单元测试表单验证