Синон макет клас

Имам клас:

export default class A {
  data: string
  constructor(data?: any) {
    if (data !== undefined) {
      this.data = data.stingValue
    }
  }
}

След това имам друг клас, който използва A конструктор вътре в публичен метод:

export default class B {
  public doSomething(data: any) {
    const a = new A(data)
    dependecy.doAnotherThing(a)
  }
}

И тест:

it(('shoud doSomething') => {
  const doAnotherThingStub = stub(B.prototype, 'doAnotherThing')
  //this part does not work, just an example of what I would like to achieve
  const doAnotherThingStub = stub(A.prototype, 'constructor').returns({dataReturendFromAConstructorStub: true})
  // end of this part
  const b = new B()
  b.doSomething({})
  expect(doAnotherThingStub.calledWith({dataReturendFromAConstructorStub: true})).to.be.true
})

И целта ми е да унищожа конструктор от клас А. Имам отделни тестове за клас А и не искам да го тествам отново. Трябва ми нещо като stub(A.prototype,'constructor'). Опитах да използвам proxyquire и мъничета, но не успях да инжектирам фалшив конструктор, или се извиква истински конструктор, или получавам нещо като: A_1.default is not a constructor. Преди имах случаи, в които трябваше да закъсам клас, който извиквам директно в рамките на тестовия случай, или да закъсам метод на класа и те са доста ясни. Но аз се боря с този случай.

Какъв би бил правилният начин за подигравка на A?


person Lukas Ignatavičius    schedule 10.02.2020    source източник


Отговори (1)


Ето решението за единичен тест, използващо proxyquire и sinon:

a.ts:

export default class A {
  private data!: string;
  constructor(data?: any) {
    if (data !== undefined) {
      this.data = data.stingValue;
    }
  }
}

b.ts:

import A from './a';

export default class B {
  public doSomething(data: any) {
    const a = new A(data);
  }
}

b.test.ts:

import sinon from 'sinon';
import proxyquire from 'proxyquire';

describe('60152281', () => {
  it('should do something', () => {
    const aStub = sinon.stub();
    const B = proxyquire('./b', {
      './a': {
        default: aStub,
      },
    }).default;
    const b = new B();
    b.doSomething({});
    sinon.assert.calledWithExactly(aStub, {});
  });
});

Резултати от тест на единица с доклад за покритие:

  60152281
    ✓ should do something (1908ms)


  1 passing (2s)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   66.67 |        0 |      50 |   66.67 |                   
 a.ts     |   33.33 |        0 |       0 |   33.33 | 4,5               
 b.ts     |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
person slideshowp2    schedule 11.02.2020
comment
Благодаря ти. Освен това sinon.assert.calledWithExactly е много по-добър вариант - person Lukas Ignatavičius; 11.02.2020