So I have a Directive that takes an input:
@Directive({
selector: '[my-directive]'
})
export class MyDirective {
@Input('some-input')
public someInput: string;
}
As you can see, the input should be a string
value. Now, I want to write a test for this Directive, and I want to test if the input satisfies the string
type:
describe('MyDirective', () => {
let fixture: ComponentFixture<DummyComponent>;
let dummy: DummyComponent;
let directive: DebugElement;
beforeEach(async(() => {
TestBed
.configureTestingModule({
imports: [
MyModule.forRoot()
],
declarations: [
DummyComponent
]
})
.compileComponents();
fixture = TestBed.createComponent(DummyComponent);
dummy = fixture.componentInstance;
directive = fixture.debugElement.query(By.directive(MyDirective));
fixture.detectChanges();
}));
it('should satisfy only a string input and error on other inputs', () => {
// How to test?
});
});
@Component({
selector: 'dummy',
template: `
<div my-directive [some-input]="'just-a-string-value'"></div>
`
})
export class DummyComponent implements OnInit {
}
How can I test whether the @Input
value(s) are of the proper type?
A mock directive in Angular tests can be created by MockDirective function. The mock directive has the same interface as its original directive, but all its methods are dummies. In order to create a mock directive, pass the original directive into MockDirective function.
To run your tests using the Angular CLI, you use the ng test command in your terminal. As a result, Karma will open up the default browser and run all the tests written with the aid of Jasmine and will display the outcome of those tests.
Input data into a DirectiveWe can also extend or modify the behavior or functionality of a directive by inputtting data into the directive.
fixture. detectChanges() tells Angular to run change-detection. Finally! Every time it is called, it updates data bindings like ng-if, and re-renders the component based on the updated data. Calling this function will cause ngOnInit to run only the first time it is called.
So it's a bit late but I came here searching for the same problem, so I'll post my solution. Here is what I did to test a directive inputs (or other properties) values :
describe('MyDirective', () => {
let fixture: ComponentFixture<DummyComponent>;
let dummy: DummyComponent;
let directive: DebugElement;
beforeEach(async(() => {
TestBed
.configureTestingModule({
imports: [
MyModule.forRoot()
],
declarations: [
DummyComponent
]
})
.compileComponents();
fixture = TestBed.createComponent(DummyComponent);
dummy = fixture.componentInstance;
directive = fixture.debugElement.query(By.directive(MyDirective));
fixture.detectChanges();
}));
it('should satisfy only a string input and error on other inputs', () => {
// needed so template is processed, inputs are updated
fixture.detectChanges();
// since we declared a ViewChild on the directive, we can access
// and test directive properties values
expect(component.directive.someInput).toEqual('just-a-string-value');
// to test the input type :
expect(component.directive.someInput).toEqual(Jasmine.any(String));
// I thought TypeScript would complain when providing a wrong type input to a directive, but no...so I guess I'll test the input type too !
});
});
@Component({
selector: 'dummy',
template: `
<div my-directive [some-input]="'just-a-string-value'"></div>
`
})
export class DummyComponent implements OnInit {
// add a reference to the directive in template
// so in your component you can access : this.directive, this.directive.someInput
ViewChild(MyDirective) directive: MyDirective;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With