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

问题描述 投票:0回答:2

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

angular jasmine karma-jasmine authorize.net accept.js
2个回答
1
投票

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

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

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

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

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


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 }
]
© www.soinside.com 2019 - 2024. All rights reserved.