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

时间:2017-12-22 20:56:58

标签: angular jasmine karma-jasmine authorize.net 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注入服务中,以便在代码尝试使用它时声明它?

2 个答案:

答案 0 :(得分:1)

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

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

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

createElementgetElementsByTagName茉莉花间谍应配置为返回正确的模拟对象。

出于可测试性原因,

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 }
]