Angular 6 & Electron: использование фиктивного класса для модульного тестирования и расширения реального класса не работает - PullRequest
0 голосов
/ 02 октября 2018

Я пытался написать модульный тест в своем электронном приложении с использованием жасмина и углового 6, но этот способ не работает.У меня есть сервис, который не требуется тестировать в моем конкретном тесте другого сервиса.Поэтому я решил издеваться над первым сервисом следующим образом:

import { Injectable } from '@angular/core';
import { TestService } from '../../services/test/test.service';

@Injectable()
export class TestServiceMock extends TestService {

    private somePath: string;

    public isFileExistent(path: string): boolean {
        return path === '\\some\\kind\\of\\path\\some.json' ? true : false;
    }
}

Я получаю следующую ошибку в коде Visual Studio:

[ts] Class 'TestServiceMock' incorrectly extends base class 'TestService'.
Types have separate declarations of a private property 'somePath'.

Мне кажется, я знаю, что эта ошибка возникает, потому чтоЭлемент «somePath» несколько отличается от «TestService», но на самом деле это не так (в моем понимании)!Это «TestService»:

import {Injectable} from '@angular/core';
import {ElectronService} from '../electron/electron.service';

@Injectable()
export class TestService {

    private somePath: string;

    constructor(private electron: ElectronService) {
        this.somePath = this.electron.remote.app.getAppPath();
    }

    public isFileExistent(path: string): boolean {
        return // some boolean after a lot of operations not needed here
    }
}

последний, но не менее важный тест, который я пишу, который показывает следующую ошибку:

[ts] Type 'typeof TestServiceMock' cannot be converted to type 'TestService'.
Property 'somePath' is missing in type 'typeof TestServiceMock'.

И тест:

import { RealService } from './real.service';
import { TestServiceMock } from '../../response-models/test/test.service.mock';
import { TestService } from '../../services/test/test.service';

describe('RealService:', () => {
    let realservice: RealService;

    beforeEach(() => {
        realservice = new RealService(TestServiceMock as TestService);
    });

    it('should be available:', () => {
        expect(realservice).toBeDefined();
    });
});

Заранее спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Ответ @M Mansour для этого вопроса является твердым.

Однако, если вы хотите протестировать это устройство без использования TestBed , вы можете предоставитькласс со шпионским объектом, созданным jasmine.createSpyObj() или реальным объектом, а затем spyOn функциями, которые вы хотели вместо этого смоделировать.

Пример использования реального объекта, а затем шпионить за функцией:

import { RealService } from './real.service';
import { TestService } from '../../services/test/test.service';

describe('RealService:', () => {
  let realService: RealService;
  let testService: TestService;

  beforeEach(() => {
    testService = new TestService();
    realService = new RealService(TestService);
  });

  it('should call isFileExistent with valid path', () => {
    spyOn(testService, 'isFileExistent').and.returnValue(true);
    realService.doSomething();
    expect(testService.isFileExistent).toHaveBeenCalledWith('VALID_PATH');
  });
});

Конечно, выполнение этого может привести к созданию всех зависимостей выше целевого объекта.Но я нашел, что это быстрее и легче понять.

0 голосов
/ 03 октября 2018

Ваш фиктивный сервис не должен расширять настоящий.Вы можете просто получить что-то вроде этого:

export class TestServiceMock {
  public isFileExistent(path: string): boolean {
    return true;
  }
}

Это определяет все открытые методы / поля, с которыми может взаимодействовать внешний код, и в случае тестирования ожидает их найти.

Тогда в вашемВ тестовый файл добавьте следующее в ваш блок beforEach, который angular предоставляет по умолчанию:

TestBed.configureTestingModule({
  declarations: [
    AppComponent
  ],
  providers: [
    {provide: TestService, useValue: new TestServiceMock()} // <- this is what you need
  ]
}).compileComponents();

Строка, отмеченная стрелкой в ​​комментарии, по сути, говорит, что предоставляют TestService, но фактически используют это значение для него.Таким образом, компоненты, которые ожидают получить TestService, получают его, но не реальный.

Используя TestBed, вы можете получить дескриптор TestService, который вы ввели (который является поддельным), и применитьшпионит за ним, чтобы манипулировать выводом его методов.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...