Search code examples
angularjasminekarma-jasmineangular-unit-test

How to fix this test case: Can't bind to 'value' since it isn't a known property of 'dls-option'


This is my day 3 in Angular unit testing with Jasmine and Karma. I'm following Pluralsight lectures. First thing first, dls-option is a component which I'm using form a library. I'll explain. I'm using a library of angular components provided by our company. In the below code <dls-dropdown> and <dls-option> are nothing but <select> and <option> tag of HTML. They've created color and font styling wrapper around it. Here's my code:

timeselector.component.html

<div>
  <h1>Choose one from the list</h1>
  <dls-dropdown>
    <dls-option *ngFor="let mode of modes" [value]="mode">
      <p>{{ mode }}</p>
    </dls-option>
  </dls-dropdown>
 </div>

timeselector.component.ts

import { Component, OnInit, ... } from '@angular/core';
...

@Component({
    selector: 'app-timeselector',
    templateUrl: './timeselector.component.html'
})
export class TimeselectorComponent implements OnInit {
    modes = ["Novice", "Intermediate", "Expert", "Beast"];
    ...
}

and here's my test file: timeselector.component.spec.ts

import { TestBed, ComponentFixture } from "@angular/core/testing"
import { TimeselectorComponent } from './timeselector.component'
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';

fdescribe('TimeselectorComponent', () => {
    let fixture: ComponentFixture<TimeselectorComponent>;
    @Component({
        selector: 'dls-label',
        template: '<div></div>'
    })
    class DlsLabelComponent {}

    @Component({
        selector: 'dls-dropdown',
        template: '<div></div>'
    })
    class DlsDropdownComponent {}


    @Component({
        selector: 'dls-option',
        template: '<div></div>'
    })
    class DlsDropdownOption {}

    beforeEach(()=>{
        TestBed.configureTestingModule({
            imports: [
                FormsModule
            ],
            declarations: [
                TimeselectorComponent,
                DlsLabelComponent,
                DlsDropdownComponent,
                DlsDropdownOption
            ]
        });
        fixture = TestBed.createComponent(TimeselectorComponent);
    })
    it('should create', ()=> {
        //expect(fixture.componentInstance).toBeTruthy();
    })
})

But my test case is failing. Here's the screenshot: enter image description here

Please help me with this and also feel free to suggest other mistakes as well. This will help me in my career.

PS: I just want to do a shallow testing. I want to mock child components.


Solution

  • I think the error message is quite precise here - the dls-options mock component is missing @Input() value.

    The timeselector.component.html is rendering dls-option and passing mode into its value input:

    <dls-option *ngFor="let mode of modes" [value]="mode">
    

    So you'll need to create that input in your mock:

    @Component({
        selector: 'dls-option',
        template: '<div></div>'
    })
    class DlsDropdownOption {
        @Input() value;
    }