【问题标题】:Failed: Template parse errors: There is no directive with "exportAs" set to "bsDatepicker" while running unit test失败:模板解析错误:运行单元测试时没有将“exportAs”设置为“bsDatepicker”的指令
【发布时间】:2019-11-13 13:59:40
【问题描述】:

我有 Angular SPA 应用程序,它具有来自 ngx-bootstrap 的日历控制。我正在从 BsDatepickerModule 导入的 NgModule 导入声明中的 ngx-bootstrap 导入 BsDatepickerModule.forRoot()。现在我有一个组件,其中包含很少的字段作为日期日历控件,当我使用 karma-jasmine 在该组件上运行单元测试时,除了该组件之外的所有测试都通过并且错误显示:

MyTestComponent > 应该创建失败:模板解析错误:有 没有将“exportAs”设置为“bsDatepicker”的指令

我尝试了以下方法:
1. 在“beforeEach”下的testbed的导入中添加“FormModule”
2. 删除node_modules文件夹,再次运行npm install

html文件代码:

<input class="form-control" placeholder="yyyy-mm-dd" formControlName="testDateOfBirth"
[ngClass]="{ 'is-invalid': displayMessage.testDateOfBirth }" bsDatepicker #dp="bsDatepicker">

spec.ts 文件:

import { FormsModule } from '@angular/forms';
describe('MyTestComponent', () => {
  let component: MyTestComponent;
  let fixture: ComponentFixture<MyTestComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports:[FormsModule],
      declarations: [ MyTestComponent],
      schemas:[NO_ERRORS_SCHEMA],
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyTestComponent);
    component = fixture.componentInstance;
    component.ngOnInit();
    fixture.detectChanges();
  });

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

预期:“应该创建”的测试应该通过
实际:我看到了这个错误:

MyTestComponent> 应该创建失败:模板解析错误:有 没有将“exportAs”设置为“bsDatepicker”的指令(“teOfBirth” [ngClass]="{ 'is-invalid': displayMessage.testDateOfBirth }" bsDatepicker [ERROR ->]#dp="bsDatepicker">

请求的html代码:

 id="wrap" class="container">
  <div class="col-md-12 col-lg-6">
    <h1>{{pageTitle}}</h1>
    <form novalidate (ngSubmit)="save()" [formGroup]="testForm">

      <div class="form-group">
        <label class="form-label required " for="EightDigitNumberId">
          What is your eightdigitNumber?
        </label>
        <input class="form-control " id="EightDigitNumberId" type="text"
          formControlName="EightDigitNumber" [ngClass]="{ 'is-invalid': displayMessage.EightDigitNumber }" mask='99999999' />
        <span class="invalid-message">{{ displayMessage.EightDigitNumber }}</span>
      </div>

      <div class="form-group">
        <label class="form-label required " for="firstNameId">
           First Name:
        </label>
        <input class="form-control " id="firstNameId" type="text" placeholder="First Name"
          formControlName="firstName" [ngClass]="{ 'is-invalid': displayMessage.firstName }" />
        <span class="invalid-message">{{ displayMessage.firstName }}</span>
      </div>

      <div class="form-group">
        <label class="form-label required " for="lastNameId">
           Last Name:
        </label>
        <input class="form-control " id="lastNameId" type="text" placeholder="last Name"
          formControlName="lastName" [ngClass]="{ 'is-invalid': displayMessage.lastName }" />
        <span class="invalid-message">{{ displayMessage.lastName }}</span>
      </div>

      <div class="form-group">
        <label class="form-label required " for="DateOfBirthId">
           Date of Birth:
        </label>
        <div class="input-group">
          <!-- 
              To add more options:
                [outsideClick]="true"
                [bsConfig]="{ dateInputFormat: 'YYYY-MM-DD', containerClass: 'theme-orange'}" 
            -->

          <input class="form-control" placeholder="yyyy-mm-dd" formControlName="DateOfBirth"
            [ngClass]="{ 'is-invalid': displayMessage.DateOfBirth }" bsDatepicker #dp="bsDatepicker">
          <div class="input-group-append">
            <button class=" fa fa-calendar" (click)="dp.toggle()" type="button"></button>
          </div>
        </div>
        <span class="invalid-message">{{ displayMessage.DateOfBirth }}</span>
      </div>

      <div class="form-group">
        <button class="btn btn-primary" type="submit" [title]="
            testForm.valid
              ? 'Save your entered data'
              : 'Disabled until the form data is valid'
          " [disabled]="!testForm.valid">
          Submit
        </button>


      </div>
    </form>

    <div class="alert alert-danger" *ngIf="errorMessage">{{errorMessage}}
    </div>
  </div>
</main>

【问题讨论】:

    标签: angular karma-jasmine ngx-bootstrap


    【解决方案1】:

    BsDatepickerModule 添加到 TestBed 导入。

      beforeEach(async(() => {
        TestBed.configureTestingModule({
          imports:[BsDatepickerModule, FormsModule],
          declarations: [ MyTestComponent],
          schemas:[NO_ERRORS_SCHEMA],
        })
        .compileComponents();
      }));
    

    【讨论】:

    • 我试过了,还是不行。错误是:失败:模板解析错误:没有 ControlContainer 的提供程序 ("

      {{pageTitle}}

      [ERROR ->]
    • 这是另一个问题。它与表单组有关。我需要查看您的完整 html 代码。
    • 编辑了原始问题以添加完整的 html 代码
    • 还将ReactiveFormsModule 添加到导入
    • 现在是一个不同的错误。错误:StaticInjectorError(DynamicTestModule)[MyTestService]-> HttpClient]: StaticInjectorError(Platform: core)[MyTestService-> HttpClient]: NullInjectorError: No provider for HttpClient!我尝试添加 HttpMock 测试客户端,但之后给了我另一个错误:错误:无法从同步测试中调用 Promise.then
    【解决方案2】:

    我知道我迟到了,但对于那些正在寻找答案的人......我对 BsDropdownModule 有确切的问题。 &lt;span #cartDropdown="bs-dropdown" dropdown"&gt;...&lt;span&gt;

    正如上面提到的ysf,我将BsDropdownModule 添加到TestBed 导入中,但必须在其后添加一个.forRoot(),就像ngx-bootstrap 文档告诉你在 app.module 中做。

      beforeEach(async(() => {
        TestBed.configureTestingModule({
          imports:[BsDropdownModule.forRoot(), ...],
          declarations: [ MyTestComponent],
          schemas:[NO_ERRORS_SCHEMA],
        })
        .compileComponents();
      }));
    

    【讨论】:

    • NO_ERRORS_SCHEMA 应该是禁止的,除非你绝对绝望
    【解决方案3】:

    确保您从 'ngx-bootstrap/datepicker' 而不是来自 'ngx-bootstrap/datepicker/public_api'

    【讨论】:

      猜你喜欢
      相关资源
      最近更新 更多
      热门标签