Angular在测试运行期间无法解析参数

时间:2018-02-15 17:10:29

标签: angular ionic-framework jasmine karma-runner karma-jasmine

我正在开发一个使用Angular 5.2.5的Ionic项目,尝试使用Jasmine和Karma构建测试设置(定位于this example,但旧版本虽然如此)。

对于已经存在且(在手动测试中)正常工作的组件LoginComponent,我已经创建了以下测试:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AuthenticationProvider } from '../../providers/authentication/authentication';
import { IonicModule, ToastController, ViewController } from 'ionic-angular';
import { LoginComponent } from './login';

describe('LoginComponent', () => {

  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        LoginComponent
      ],
      imports: [
        IonicModule.forRoot(LoginComponent),
      ],
      providers: [
        { provide: AuthenticationProvider, useValue: {} as AuthenticationProvider },
        { provide: ViewController, useValue: {} as ViewController },
        { provide: ToastController, useValue: {} as ToastController },
      ]
    })
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(LoginComponent);
    component = fixture.componentInstance;
  });

  it('should create component', () => expect(component).toBeDefined())
});

待测组件:

import { Credentials } from '../../model/credentials';
import { AuthenticationProvider } from '../../providers/authentication/authentication';
import { ViewController, ToastController } from 'ionic-angular';

@Component({
  selector: 'login',
  templateUrl: 'login.html'
})
export class LoginComponent {

  public registration = false;
  public readonly credentials = new Credentials('', '');

  constructor(
    private authentication: AuthenticationProvider,
    private view: ViewController,
    private toast: ToastController,
  ) {
  }

  // (methods omitted for brevity)
}

启动Karma后,编译工作并触发测试。然后,它在运行时失败,并显示以下错误消息:

Error: Can't resolve all parameters for LoginComponent: (?, ?, ?).
    at syntaxError (webpack:///node_modules/@angular/compiler/esm5/compiler.js:485:21 <- test-config/karma-test-shim.js:72827:34)
    at CompileMetadataResolver._getDependenciesMetadata (webpack:///node_modules/@angular/compiler/esm5/compiler.js:15700:0 <- test-config/karma-test-shim.js:88042:35)
    at CompileMetadataResolver._getTypeMetadata (webpack:///node_modules/@angular/compiler/esm5/compiler.js:15535:0 <- test-config/karma-test-shim.js:87877:26)
    at CompileMetadataResolver.getNonNormalizedDirectiveMetadata (webpack:///node_modules/@angular/compiler/esm5/compiler.js:15020:0 <- test-config/karma-test-shim.js:87362:24)
    at CompileMetadataResolver._getEntryComponentMetadata (webpack:///node_modules/@angular/compiler/esm5/compiler.js:15848:25 <- test-config/karma-test-shim.js:88190:45)
    at webpack:///node_modules/@angular/compiler/esm5/compiler.js:15829:29 <- test-config/karma-test-shim.js:88171:48
[...]

对我来说,这听起来像构造函数参数的依赖注入失败。但是我已经在我的测试模块配置中列出了所有这些类型的相应提供者,所以如果我没有弄错的话应该使用它们。

我错过了什么?

对于它的价值,有没有办法让Angular报告有关错误的更多细节,例如:哪些参数特别无法解决?

更新

额外的回火表明,即使找不到每个参数也是如此。也就是说,即使构造函数只是

constructor(private toast: ToastController) { }

发生相同的错误(但只有一个问号用于一个未解析的参数)。由于ToastController是一个离子角度的内置函数,因此可能会排除循环依赖性问题。

更新2

调试显示问题不在注册提供商一边,但首先无法确定参数类型。

在JIT编译器中的某个时刻,以下代码段产生[undefined],对应于上面提到的一个参数(toast):

this._reflector.parameters(typeOrFunc)

看起来类型信息在编译过程中会以某种方式丢失。

2 个答案:

答案 0 :(得分:0)

你能尝试做这样的事情并在评论中写下它是否正常工作?

Capybara.register_driver :selenium do |app|
  options = Selenium::WebDriver::Chrome::Options.new

  options.add_argument('--headless')
  options.add_argument('--no-sandbox')
  options.add_argument('--disable-gpu')
  options.add_argument('--disable-popup-blocking')
  options.add_argument('--window-size=1366,768')

  options.add_preference(:download, directory_upgrade: true,
                                prompt_for_download: false,
                                default_directory: 
 '/User/paulo/projects/app/tmp')

  options.add_preference(:browser, set_download_behavior: { behavior: 'allow' })

  driver = Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)

  bridge = driver.browser.send(:bridge)

  path = '/session/:session_id/chromium/send_command'
  path[':session_id'] = bridge.session_id

  bridge.http.call(:post, path, cmd: 'Page.setDownloadBehavior',
                                params: {
                                  behavior: 'allow',
                                  downloadPath: '/User/paulo/projects/app/tmp'
                            })

  driver
end

答案 1 :(得分:0)

我终于设法解决了这个问题。

我的karma-test-shim.js中有一个(未使用的)导入(一个帮助加载角度测试代码并初始化测试环境):

import { AppModule } from '../src/app/app.module';

删除它最终使我的测试变为绿色。

坦率地说,为什么这会破坏依赖注入,或者它与错误消息和我的调试结果有什么关系。