Ramona
Ramona

Reputation: 255

Testing a component with dependencies using karma & jasmine

I'm new to angular 2 and I have some problems testing my code. I use the jasmine testing framework and the karma test runner to test my app.

I have a component (called GroupDetailsComponent) that I want to test. This component uses two services (GroupService & TagelerServie, both have CRUD methods to talk to an API) and some pipes in the html file. My component looks like this:

import 'rxjs/add/operator/switchMap';
import { Component, Input, OnInit } from '@angular/core';
import { Tageler } from '../../tagelers/tageler';
import { TagelerService } from '../../tagelers/tageler.service';
import { Params, ActivatedRoute } from '@angular/router';
import { GroupService} from "../group.service";
import { Group } from '../group';


@Component({
  selector: 'app-group-details',
  templateUrl: 'group-details.component.html',
  styleUrls: ['group-details.component.css'],
})

export class GroupDetailsComponent implements OnInit {
  @Input()
  tageler: Tageler;
  tagelers: Tageler[];
  group: Group;

  constructor(
    private route: ActivatedRoute,
    private groupService: GroupService,
    private tagelerService: TagelerService) {
  }

  ngOnInit() {
    console.log("Init Details");
    this.route.params
      .switchMap((params: Params) => this.groupService.getGroup(params['id']))
      .subscribe(group => this.group = group);

    this.tagelerService
      .getTagelers()
      .then((tagelers: Tageler[]) => {
        // some code
          }
          return tageler;
        });
      });
  }
}

And the test file looks like this:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { GroupDetailsComponent } from './group-details.component';
import { FilterTagelerByGroupPipe } from '../../pipes/filterTagelerByGroup.pipe';
import { SameDateTagelerPipe } from '../../pipes/sameDateTageler.pipe';
import { CurrentTagelerPipe } from '../../pipes/currentTageler.pipe';
import { NextTagelerPipe } from '../../pipes/nextTageler.pipe';
import { RouterTestingModule } from '@angular/router/testing';
import { GroupService } from '../group.service';
import { TagelerService } from '../../tagelers/tageler.service';

describe('GroupDetailsComponent', () => {

  let component: GroupDetailsComponent;
  let fixture: ComponentFixture<GroupDetailsComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ 
        GroupDetailsComponent,
        FilterTagelerByGroupPipe,
        SameDateTagelerPipe,
        CurrentTagelerPipe,
        NextTagelerPipe, ],
      imports: [ RouterTestingModule ],
      providers: [{provide: GroupService}, {provide: TagelerService}],
    })

    fixture = TestBed.createComponent(GroupDetailsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

  });

  class MockGroupService {
    getGroups(): Array<Group> {
      let toReturn: Array<Group> = [];
        toReturn.push(new Group('Trupp', 'Gruppe 1'));
      return toReturn;
    };
  }


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

I read the angular 2 documentation about testing and a lot of blogs, but I still don't really understand how to test a component that uses services and pipes. When I start the test runner, the test 'should create component' fails and I get the message that my component is not defined (but I don't understand why). I also don't understand how I have to inject the services and pipes. How do I mock them the right way?

I hope that someone can give me helpful advice!

Ramona

Upvotes: 0

Views: 1156

Answers (1)

Aniruddha Das
Aniruddha Das

Reputation: 21698

You can use spyOn to fake the call in jasmine.

spyOn(yourService, 'method').and.returnValue($q.resolve(yourState));

Upvotes: 1

Related Questions