2013-12-20 2 views
4

테스트 할 node.js 코드가 있습니다. 이들은 함수를 반환하는 모듈입니다 (module.exports = function() {...}). 함수 내부에는 다른 모듈이 필요합니다. 이제 우리는이 모듈을 모의하고 싶습니다. 아래 예제를 참조하십시오 :node.js에서 함수를 반환하는 모의 모듈

// userRepo.js 
module.exports = function(connection) { 
    // init the repo 
    var repo = DB.connect(connection);  

    // add validation function 
    repo.validate = function(data, cb) { 
     // do validation stuff 
     cb(error, result); 
    }; 

    return repo; 
}; 

// userController.js 
module.exports = function(config) { 
    var repo = require('userRepo.js')(config.connectionStringToUserDB) 
    var pub = {}; 

    pub.create = function(data, cb) { 
     repo.validate(data, function(err, res) { 
      // do some stuff 
     }; 
    }; 

    return pub; 
} 

// the test 
var sut = require('userController.js')(anyConfig); 

sut.create({}, function(err, res) { 
    // do some assertions here 
}; 

그래서 테스트에서 우리는 repo.validate() 함수를 조롱하거나 스터핑하려고합니다. 그러나 지금까지 우리는 이것을하는 방법을 찾지 못했습니다. 우리가 테스트 한 모든 node.js 조롱 프레임 워크/libs는 모듈을 모방 한 다음 내보내기를 무시할 수 있습니다. 그러나 우리의 경우 모듈은 함수를 반환하고 컨트롤러에서는 repo가 ​​이미 인스턴스화됩니다.

내 설명을 이해할 수 있기를 바랍니다 .-)

도움 주셔서 감사합니다.

답변

2

코드에서 뭔가를 변경하지 않고도 문제를 해결할 수 있다고 생각하지 않습니다. 이는 repo 변수가 userRepo.js의 개인 변수이기 때문입니다. 그러나 나는 그런 상황을 정말 좋아합니다, 왜냐하면 당신은 모듈이 적절히 설계되지 않았고 충분히 테스트 될 수 없기 때문입니다. 나는 그것을 그렇게 쓸 것이다.

// userRepo.js 
module.exports = function(connection) { 

    var api = {}, repo; 

    api.setRepo = function(r) { 
     repo = r; 
    } 
    api.getRepo = function() { 
     return repo; 
    } 
    api.init = function() { 

     // init the repo 
     repo = repo || DB.connect(connection); 

     // add validation function 
     repo.validate = function(data, cb) { 
      // do validation stuff 
      cb(error, result); 
     }; 

    } 

    return api; 
}; 

그래서, 당신은 repo varialbe을로 mockup 및 사용자 정의 validate 메소드하여 자신의 변형을 통과 할 수있을 것 같은 일을. 물론 문제는

var userRepo = require("./userRepo.js")(connection).init(); 

var userRepo = require("./userRepo.js")(connection) 

에서 userRepo.js를 사용하는 곳은 장소를 변경해야한다는 것입니다하지만 그것은 가치. 때문에 귀하의 테스트에서 당신은 쓸 수 있습니다 :

var userRepo = require("./userRepo.js")(connection).setRepo(customRepo).init(); 

또는

var userRepo = require("./userRepo.js")(connection); 
var repo = userRepo.getRepo(); 
repo.validate = function() { 
    // custom stuff here 
} 
userRepo.init(); 

그래서 내 조언이다 : 뭔가 자신에게 물어 쓰기 시작하기 전에 "나는 그것을 테스트하는거야 어떻게?".

+0

당신 말이 맞습니다. 쉽게 조롱 할 수 있도록 레오를 삽입하거나 가져 오거나 설정하는 것이 좋습니다. 내 문제는 컨트롤러가 호출 될 때 호출자가 레포를 알지 못한다는 것입니다. 컨트롤러 만 알고 있습니다. 하지만 주입 된 repo가 ​​비어 있으면 기본값을 사용합니다. – 4kochi

관련 문제