Как издеваться над наблюдаемым и получать от введённого издевательства - PullRequest
0 голосов
/ 15 ноября 2018

Я новичок в тестировании и уже потерян.

У меня есть сервис, который я хочу протестировать:

animation.service.ts

... 
public constructor(private animationStateService: AnimationStateService,
                   frameStateService: FrameStateService) {

     frameStateService.changedAvailableFrames
            .pipe(
                ...
                // Some code in pipe
                ...
            )
            ).subscribe(() => {
                ...
                // Some code in subscribe
                ...
            }
        ) }

public start(): void {

    if (this.animationStateService.status !== AnimationStatus.Stopped) {
        return;
    }

    this.animationStateService.changeStatus(AnimationStatus.Preloading);
    this.preloaderService.preloadAllFrames()
        .subscribe(
            () => {
                this.run();
            }
        ); 
}
...

Внедренные услуги:

frame-state.service.ts

@Injectable()
export class FrameStateService {

private changedAvailableFramesSubject: Subject<LayerId> = new Subject();
public changedAvailableFrames: Observable<LayerId> = this.changedAvailableFramesSubject.asObservable();

public constructor() {}
...

animation-state.service.ts

@Injectable()
export class AnimationStateService {

public get status(): AnimationStatus { return this.state.animation.status; }
...

В моих тестах я хочу высмеивать changedAvailableFrames из FrameStateService, а также status из AnimationStateService.

Что я уже сделал:

animation.service.spec.ts

describe("AnimationService", () => {

    let animationService: SpyObj<AnimationService>;
    let animationStateService: SpyObj<AnimationStateService>;
    let frameStateService: SpyObj<FrameStateService>;

    beforeEach(() => {

        const spyFrameStateService = createSpyObj("FrameStateService", [""]);
        const spyAnimationStateService = createSpyObj("AnimationStateService", ["changeStatus", "status"]);

        TestBed.configureTestingModule({
        providers: [
            AnimationService,
            {provide: FrameService, useValue: spyFrameService},
            {provide: AnimationStateService, useValue: spyAnimationStateService},
            ]
        });

        animationService = TestBed.get(AnimationService);
        animationStateService = TestBed.get(AnimationStateService);
        frameStateService = TestBed.get(FrameStateService);

        frameStateService.changedAvailableFrames.and.returnValue(of());

    });

    it("Should call changeStatus", () => {

        // Arrange
        animationStateService.status.and.returnValue(AnimationStatus.Stopped);

        // Act
        animationService.start();

        // Assert
        expect(animationStateService.changeStatus).toHaveBeenCalled();
    });

})

Ошибки, которые я получил:

TypeError: Cannot read property 'pipe' of undefined

TypeError: Cannot read property 'status' of undefined

На данный момент я полностьюпотерян, и я не знаю, как поступить.

1 Ответ

0 голосов
/ 15 ноября 2018

const spyFrameStateService = createSpyObj("FrameStateService", [""]);

Создает фиктивный объект без методов и свойств (второй аргумент должен быть пропущен для этого случая. Если вы хотите использовать макет с методом hello, вы создадите его как createSpyObj("FrameStateService", ["hello"]);).К сожалению, используя createSpyObj, вы не можете создавать свойства.

Но вам нужно свойство changedAvailableFramesSubject, верно?Потому что он подписан вашим протестированным сервисом.

Так что вместо насмешки с помощью createSpyObj создайте простой объект:

{provide: FrameStateService, useValue: { changedAvailableFramesSubject: new Subject() },

И заставьте его излучать в любое время:

const frameStateService = TestBed.get(FrameStateService);
frameStateService.changedAvailableFramesSubject.next('your emitted value');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...