2

I am working on unit-testing with jasmine and karma an angular component. In the template-component a custom dropdown component is used:

   <div class="my-modal-body">
        <form [formGroup]="form" class="form-horizontal">
            <div class="padding-dropdown">
                <my-form-wrapper
                    label="Dateiformat"
                    labelClass="col-lg-4 two-col-label-size"
                    inputClass="col-lg-8 two-col-input-size"
                >
                    <my-dropdown
                        [items]="exportOptionen"
                        formControlName="dateiTyp"
                        (selectedChange)="exportFileChange($event)"
                    >
                    </my-dropdown>
                </my-form-wrapper>
            </div>

In my testing I try to test the value change, but can't get it working. However I try to set the value, the exportFileChange is not triggered. And I know that the component is correct, because it's already in production. So it has to be the test that errors.

Here is my test:

    it('dateiTyp auswahl excel', waitForAsync(() => {
        spyOn(component, 'exportFileChange');
        dateiTyp.setValue('Excel');
        component.dateiTyp.setValue('Excel', { emitEvent: true });
        fixture.detectChanges();
        fixture.whenStable().then(
            () => {
                expect(component.exportFileChange).toHaveBeenCalled();
                let exDiv = fixture.debugElement.query(By.css("#excelExportDiv"));
                expect(exDiv).not.toBeNull();
            }
        );
    }));

When changing the selection the exportFileChange(event) method should be called and in the template an div appears. The exportFileChange-Method in the component just changes an boolean. I tested changing the boolean in the test and that worked, but the event still wasn't triggered.

Here are the most relevant parts of the setup:

describe('ExportModalComponent', () => {
   [...]
   let dateiTyp: jasmine.SpyObj<FormControl>;
   let dateiTypChange: Subject<string>;
[...]

beforeEach( waitForAsync(() => {
[...]
  dateiTyp = jasmine.createSpyObj('dateiTyp', ['value', 'setValue']);
  formGroup.get.withArgs('dateiTyp').and.returnValue(dateiTyp);
  dateiTypChange = new Subject();
  Object.defineProperty(dateiTyp, 'valueChanges', { value: dateiTypChange });
[...]

and my-dropdown.component.d.ts:

export declare class myDropdownComponent implements ControlValueAccessor, OnInit, OnChanges 
{ [...] }

I can change the ExportModal-template or the ExportModal-component but I can't change the implementation or use of myDropdownComponent.

I am grateful for every help!

Thanks!

1 Answer 1

2

This is not a complete answer but it should help you.

This is a good read. In these kind of situations, I just use triggerEventHandler on the DebugElement.

Something like this:

it('should do abc', () => {
   // get a handle on the debugElement
   const myDropDown = fixture.debugElement.query(By.css('my-dropdown'));
   // the first argument is the name of the event you would like to trigger
   // and the 2nd argument of type object (or anything) is the $event you want to mock for the calling function
   myDropDown.triggerEventHandler('selectedChange', { /* mock $event here */});
   // continue with tests
});

I am not entirely sure how your components are wired but that's the best way I have found to raise custom events for custom components.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.