2

I want to run unit tests on my component which has ng2-dragula.

However, when I run a simple unit test on the component, I get the error

TypeError: Cannot read property 'setOptions' of undefined

component.html

<div [dragula]="'section-bag'"
     [dragulaModel]='form.sections'>
  <div *ngFor="let section of form.sections">
    <div class="drag-handle__section"></div>
  </div>
</div>

component.ts

import { Component, Input } from '@angular/core';
import { DragulaService } from 'ng2-dragula';
...


export class MyComponent {

  @Input() form;

  constructor(private dragulaService: DragulaService) {
    dragulaService.setOptions('section-bag', {
      moves: (el, container, handle) => {
        return handle.classList.contains('drag-handle__section');
      }
    });
  }

  ...
}

component.spec.ts

import { DragulaService } from 'ng2-dragula';
...


describe('Test for MyComponent', () => {
  let comp: MyComponent;
  let fixture: ComponentFixture<MyComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ MyComponent ],
      providers: [
        { provide: DragulaService }
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    comp = fixture.componentInstance;
    comp.form.sections = [];
    comp.form.sections.push(new FormSection());

    fixture.detectChanges();
  });

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

});

I guess that Dragula is not being imported correctly, so how do I add Dragula as a provider in the test to use it in the component's constructor?

I've looked at Angular2 unit testing : testing a component's constructor which seems related, but I can't resolve the error.

Note: I'm not so fussed about unit testing Dragula; I want to test other functionality in the component, but this error isn't allowing any further tests to run.

timray
  • 588
  • 1
  • 9
  • 24

1 Answers1

2

Change the way you are providing the DragulaService. If you provide it like

{ provide: DragulaService }

then you should either mention useClass or useValue attribute to it.

For ex : { provide: DragulaService, useClass : MockService }

If you are not interested to mock, then directly add it to providers array.

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ MyComponent ],
      providers: [
         DragulaService  // see this line
      ]
    })
    .compileComponents();
}));
Amit Chigadani
  • 28,482
  • 13
  • 80
  • 98
  • 1
    Thanks @Amit Chigadani, my hero! – timray Aug 01 '18 at 10:35
  • Hello @Amit Chigadani, can you help me with this question : https://stackoverflow.com/questions/61725741/uncaught-typeerror-shown-in-karma-when-unit-testing-in-angular ... Sorry for posting like this but i kind of need help. Please tell me if there is a better way. – KL_KISNE_DEKHA_HAI May 11 '20 at 08:55
  • Hello @Amit Chigadani, can you help me with this question https://stackoverflow.com/questions/61719672/returning-2-different-values-using-using-a-mock-service-while-unit-testing-in-an .. i tried to explain and change it a bit more. – KL_KISNE_DEKHA_HAI May 17 '20 at 07:41