【问题标题】:How to test service observable in a component with assignments如何在具有分配的组件中测试可观察的服务
【发布时间】:2020-04-05 11:17:32
【问题描述】:

我有一个订阅服务中可观察对象的组件。然后,一旦解决了订阅,我就会将获得的值分配给组件属性。什么是正确的测试方法?

组件

import { ANIMATIONS } from './../../helpers/animations';
import { Component, Input } from '@angular/core';
import { RickMortyService, ICharacter } from '../../services/rick-morty.service';

@Component({
    // tslint:disable-next-line:component-selector
    selector: 'character-details',
    templateUrl: './character-details.component.html',
    styleUrls: ['./character-details.component.scss'],
    animations: [
        ANIMATIONS.fade,
        ANIMATIONS.scaleUpEnter
    ]
})
export class CharacterDetailsComponent {
    @Input() character: ICharacter;
    requestLoading: boolean;

    constructor(private rickMortyService: RickMortyService) { }

    getEpisodeCharacters() {
        this.requestLoading = true;
        this.rickMortyService.getEpisodeCharacters(this.character.episode[0].id).subscribe(characters => {
            this.character.episode[0].characters = characters;
            this.requestLoading = false;
        });
    }
}

单元测试

import { RickMortyService } from "src/app/services/rick-morty.service";
import { By } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { AngularFontAwesomeModule } from 'angular-font-awesome';
import { Apollo } from 'apollo-angular';
import { fakeAsync, async, ComponentFixture, TestBed, tick } from '@angular/core/testing';

import { CharacterDetailsComponent } from './character-details.component';
import { TooltipDirective } from 'src/app/directives/tooltip.directive';
import { ICharacter } from '../../services/rick-morty.service';

const mockCharacter: ICharacter = {
    id: '1',
    image: 'http://rickandmortyapi.com/api/character/avatar/1.jpeg',
    name: 'Rick Sanchez',
    status: 'Alive',
    species: 'Human',
    gender: 'Male',
    origin: {
        id: '1',
        name: 'Earth (C-137)',
        type: 'Planet',
        dimension: 'Dimension C-137'
    },
    location: {
        id: '20',
        name: 'Earth (Replacement Dimension)',
        type: 'Planet',
        dimension: 'Replacement Dimension'
    },
    episode: [
        {
            id: '31',
            air_date: 'October 1, 2017',
            name: 'The Rickchurian Mortydate',
            episode: 'S03E10'
        }
    ]
};

const episodeCharactersPageMock: ICharacter[] = [
    {
        id: '',
        image: '',
        name: 'Rick Sanchez',
        status: '',
        species: '',
        gender: '',
        origin: {
            id: '',
            name: '',
            type: '',
            dimension: ''
        },
        location: {
            id: '',
            name: '',
            type: '',
            dimension: ''
        },
        episode: []
    },
    {
        id: '',
        image: '',
        name: 'Morty Smith',
        status: '',
        species: '',
        gender: '',
        origin: {
            id: '',
            name: '',
            type: '',
            dimension: ''
        },
        location: {
            id: '',
            name: '',
            type: '',
            dimension: ''
        },
        episode: []
    }
];

describe('CharacterDetailsComponent', () => {
    let component: CharacterDetailsComponent;
    let fixture: ComponentFixture<CharacterDetailsComponent>;
    let service: RickMortyService;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [AngularFontAwesomeModule, BrowserAnimationsModule],
            declarations: [CharacterDetailsComponent, TooltipDirective],
            providers: [Apollo]
        })
            .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(CharacterDetailsComponent);
        component = fixture.componentInstance;
        component.character = mockCharacter;
        service = TestBed.get(RickMortyService);
        fixture.detectChanges();
    });

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

    it('should get all characters of a specific episode when calling function', async () => {
      // test to be written here
    });
});

还应该注意的是,我正在使用 Apollo 来获取必要的数据。这在服务本身中进行了测试。

【问题讨论】:

    标签: javascript angular unit-testing


    【解决方案1】:

    您必须模拟 getEpisodeCharacters 方法并从中返回一个 observable,然后您可以检查从 getEpisodeCharacters 方法返回的模拟值是否在 this.character.episode[0].characters 中分配。有点像这样-

      it('should get all characters of a specific episode when calling function', async () => {
        spyOn(service, 'getEpisodeCharacters').and.returnValue(of(['test']));
        component.getEpisodeCharacters();
        expect(component.character.episode[0].characters).toEqual(['test']); // you will have to initialise component.character.episode[0] behorehand.
      });
    

    【讨论】:

      【解决方案2】:

      从 rxjs 导入 of 运算符。

      import { of } from 'rxjs';
      
      
      it('should get all characters of a specific episode when calling function', async () => 
       {
         spyOn(service, 'getEpisodeCharacters').and.returnValue(of(['episodeCharactersPageMock']));
         component.getEpisodeCharacters();
         expect(component.character.episode[0].characters).toEqual(['episodeCharactersPageMock']); });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多