2016-12-16 2 views
1

헬퍼 클래스를 사용하는 클래스가 있는데,이 클래스가 올바르게 구성되었는지 확인하고 싶습니다. 그래서, 나는 내 수업에서 "생성자"방법을 스텁하기 위해 노력하고있어,하지만 난 분명히 바로 그 일을하고 있지 않다 :es6 공동 작업자 모의 구성

"use strict"; 

class Collaborator { 
    constructor(settings) { 
    console.log("Don't want this to be called!") 
    this.settings = settings; 
    } 
} 

class ThingToTest { 
    constructor(settings) { 
    this.helper = new Collaborator(settings); 
    } 
} 

const assert = require("assert"); 
const sinon = require("sinon"); 

describe("ThingToTest",() => { 
    let settings = "all the things" 

    context("spying on constructor",() => { 
    let spy = sinon.spy(Collaborator, "constructor") 
    after(() => spy.restore()) 
    describe("constructor",() => { 
     it("creates a Collaborator with provided settings",() => { 
     new ThingToTest(settings); 
     sinon.assert.calledWith(spy, settings) 
     }) 
    }) 
    }) 

    context("spying on prototype constructor",() => { 
    let spy = sinon.spy(Collaborator.prototype, "constructor") 
    after(() => spy.restore()) 
    describe("constructor",() => { 
     it("creates a Collaborator with provided settings",() => { 
     new ThingToTest(settings); 
     sinon.assert.calledWith(spy, settings) 
     }) 
    }) 
    }) 

    context("stub constructor",() => { 
    before(() => { 
     sinon.stub(Collaborator, "constructor", (settings) => { 
     console.log("This should be called so we can inspect", settings); 
     }) 
    }) 
    after(() => { Collaborator.constructor.restore() }) 
    describe("constructor",() => { 
     it("creates a Collaborator with provided settings",() => { 
     new ThingToTest(settings); 
     }) 
    }) 
    }) 

    context("stub prototype constructor",() => { 
    before(() => { 
     sinon.stub(Collaborator.prototype, "constructor", (settings) => { 
     console.log("This should be called so we can inspect", settings); 
     }) 
    }) 
    after(() => { Collaborator.prototype.constructor.restore() }) 
    describe("constructor",() => { 
     it("creates a Collaborator with provided settings",() => { 
     new ThingToTest(settings); 
     }) 
    }) 
    }) 

}) 

을이이 (바람직하지 않은) 결과 생산 실행 :

ThingToTest 
    spying on constructor 
     constructor 
Don't want this to be called! 
     1) creates a Collaborator with provided settings 
    spying on prototype constructor 
     constructor 
Don't want this to be called! 
     2) creates a Collaborator with provided settings 
    stub constructor 
     constructor 
Don't want this to be called! 
     ✓ creates a Collaborator with provided settings 
    stub prototype constructor 
     constructor 
Don't want this to be called! 
     ✓ creates a Collaborator with provided settings 

을 스파이가 "래핑 된 생성자를 랩핑하려고했습니다."라고 두려워하는 오류를 테스트하기 전에 스텁 테스트가 스텁 테스트를 수행 한 이후 일종의 스터 빙처럼 보입니다. 따라서 Collaborators 생성자를 조롱하는 방법을 명확하게 파악하는 것은 내가 잘못하고있는 것의 절반에 지나지 않습니다. . . 나는 생성자를 올바르게 복원하지 못하고있다. 어떤 제안?

context("checking Collaborator in a more integration style test",() => { 
    describe("constructor",() => { 
     it("creates a Collaborator with provided settings",() => { 
     let thing = new ThingToTest(settings); 
     assert.equal(thing.helper.settings, settings) 
     }) 
    }) 
    }) 

이 통과 :

+0

나는 sinon에 관해서 아무 것도 모른다. 그래서'class' 정의에서'constructor'을 통해 생성 된 함수는'class'에 의해 생성 된 식별자로 할당되는 함수라는 것을 지적하겠다. 정의. 즉'class Collaborator {constructor() {}}'에서'constructor() {} '에 의해 생성 된 함수는 식별자'Collaborator '에 의해 액세스됩니다. 위의 경우 Collaborator.constructor (해당되지 않음)와 Collaborator.prototype.constructor (해당 될 것입니다. Collaborator와이 둘 모두를 참조하십시오. 같은 기능). FWIW. –

+0

코드를 올바르게 읽는다면 조롱 할 때 'Collaborator' 변수의 값을 바꾸지 않을 것입니다 (사실상 변수 임). 적어도 하나의 장소에서 당신은 아마도'Collaborator.prototype.constructor' 속성의 값을 대체 할 것이지만'new Collaborator'에 의해 사용되지 않습니다. –

+0

감사합니다. T.J. 그래서 Collaborator와 ThingToTest 클래스를 자신의 파일로 옮기고 "module.exports = Collaborator/ThingToTest"를 추가했습니다. 그렇다면 나의 ExampleFile에서, 나는'const Collaborator = require ("../ Collaborator")'와'const ThingToTest = require ("../ ThingToTest")'를했지만, 아무것도 변경하지 않았다.그게 당신이 염두에 두었던 것인지 확신 할 수 없지만, 시도 할 수있는 다른 아이디어가 있다면, 나는 어떤 것에 대해서도 기꺼이 줄 것입니다. –

답변

0

이 나는이 (당신이 제안이있는 경우 그러나, 자신으로부터 나를 구원하시기 바랍니다)를 사용하여 끝낼 수 있습니다 당분간 그러나, 하지 내가 원하는 솔루션 공동 작업자가 올바른 설정을 가지고 있는지 확인합니다. 하지만 이제는 공동 작업자 생성자를 리팩터링하려면 ThingToTest를 중단합니다. 다시 말하지만, 나는 아직도 누군가가이 클래스를 실제로 테스트 할 수있는 방법을 제안 할 수 있기를 희망하고있다.

0

이것이 내 최종 답변이 아니지만 지금까지 찾은 최고의 솔루션이므로 proxyquire를 사용하게되었습니다. 어떻게 작동하는지 보여주기 위해 테스트중인 클래스를 자신의 디렉토리로 분리하고 테스트 파일을 하위 "test"디렉토리에 분리했습니다. 이것은 을 설명합니다. proxyquire의 경로가 있습니다 (어느 정도 시간이 필요했습니다).

/Collaborator.js

"use strict" 

class Collaborator { 
    constructor(settings) { 
    console.log("Don't want this to be called!") 
    this.settings = settings; 
    } 
} 

module.exports = Collaborator 

/ThingToTest.js

"use strict" 

const Collaborator = require("./Collaborator") 

class ThingToTest { 
    constructor(settings) { 
    this.helper = new Collaborator(settings) 
    } 
} 

module.exports = ThingToTest 

/test/ExampleTest.js

"use strict"; 

const proxyquire = require('proxyquire') 
const mockCollaborator = sinon.stub(); 
const ThingToTest = proxyquire("../ThingToTest", { "./Collaborator" : mockCollaborator }) 

const assert = require("assert"); 
const sinon = require("sinon"); 

describe("ThingToTest",() => { 
    let settings = "all the things" 

    context("checking Collaborator in a more integration style test",() => { 

    describe("constructor",() => { 
     it("creates a Collaborator with provided settings",() => { 
     let thing = new ThingToTest(settings); 
     assert.equal(mockCollab.firstCall.calledWith(settings)) 
     }) 
    }) 
    }) 
}) 

참고 방법 : 그래서, 여기에 내가 함께 결국 무엇 내부 경로는 "ThingToTest"가 사용하는 것과 일치합니다. 은이 아닙니다. 0 테스트 클래스에서 경로. 이 도움이 다른 사람들에게도 도움이되기를 바랍니다. 그러나 나는 여전히 다른 아이디어와 제안에 열려 있습니다!

관련 문제