Как смоделировать метод класса, который инициализируется внутри другого класса в машинописи, используя ts mockito? - PullRequest
0 голосов
/ 26 марта 2019

Это мой класс, который я хочу протестировать, используя тестовый фреймворк мокко-чай в машинописи Я использую ts-mockito для насмешек.

export class ClassA implements IClassA {

    private classAResource: IClassAResource;

    constructor(){
         this.classAResource= new ClassAResource();
    }

    public async cancel(jobid){
       const job = this.classAResource.getJob(jobid);
       //cancel logic
    }
}

Класс ClassAResource выглядит следующим образом,

export class StreamResource implements IStreamResource {

private jobs: Map<string, Job>;

 constructor(){
 this.jobs= new Map();
 }

public async createJob(): Promise<Job> {
//add the job to map
}

public async getJob(jobid): Promise<Job>{
//return the specified job item from map
}


}

В моем тесте я пытаюсь смоделировать метод getJob ClassAResource следующим образом:

const classAResource: IClassAResource = new ClassAResource ();
 const classAResourceSpy = spy(classAResource);

 when(classAResourceSpy.getJob(anyString())).thenResolve(job); 

И я вызываю метод отмены ClassA следующим образом:

classA.cancel(jobid)

Я ожидаю, что вызов метода getJob в методе cancel будет смоделирован и возвращен объект задания.

Но тест не соответствует моим ожиданиям. Mock не входит в картину, и getJob () переходит к фактической реализации и возвращает undefined.

Я читал в Интернете, эта проблема из-за инициализации конструктора в классе ClassAResource.

Я удалил конструктор и попробовал, и теперь макет getJob работает.

Но мне нужен конструктор для создания экземпляра объекта карты и способности поддерживать задания.

Есть ли какой-нибудь обходной путь, через который я могу смоделировать getJob () с конструктором на месте?

Я что-то здесь не так делаю?

Я относительно новичок в машинописи и ts-mockito, и любая помощь очень ценится.

1 Ответ

1 голос
/ 26 марта 2019

Это на самом деле не имеет ничего общего с TypeScript, а скорее с проблемой тестируемости из-за нарушения принципа Dependency Inversion .
Создание экземпляров членов в конструкторе класса вызывает проблему тестируемости, поскольку контроль над созданием экземпляра находится в руках тестируемого кода (a.k.a «тестируемый модуль», «тестируемый класс» и т. Д.). Это означает, что вы практически не контролируете, какой экземпляр будет иметь класс, который вы тестируете.

Существуют некоторые насмешливые библиотеки, которые допускают «враждебное поглощение» экземпляров определенных классов (по крайней мере, для Java, см. PowerMock ), но их следует использовать очень экономно, если вообще, так как они способствуют увековечению отсутствия тестируемости.

Вместо создания экземпляра IClassAResource из конструктора ClassA, вы должны либо получить экземпляр с помощью инжекции (DI, конструктор, метод установки и т. Д.), Либо по крайней мере использовать фабрику / конструктор. Таким образом, ваш класс станет тестируемым и ваш дизайн будет улучшен.

В общем, вы должны придерживаться всех принципов SOLID , так как они, по крайней мере на данный момент, считаются наиболее точным и кратким набором хороших принципов проектирования ООП.

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