2015-02-02 4 views
3

나는 이것이 몇 번 논의되었습니다 알아요. 어쨌든, 모든 솔루션이 제 요구 사항에 (완벽하게) 맞지 않는 것 같습니다. 나는 다음과 같은 코드를 가지고있다 :유닛 테스트 익스프레스 라우터

router.js: 
------------------ 
var Router = function(app, resourceName, controller) { 
    //Create 
    app.post('/api/' + resourceName, function(req, res) { 
     console.log('Incoming request: ' + resourceName + ' (POST)'); 
     controller.create(req, res); 
    }); 
}; 

module.exports = Router; 

이것은 매우 일반적인 "라우터"이다.

var app = express(); 
var userController = ... 
var userRouter = new Router(app, 'Users', userController); 

그래서 나는 자원 당 파일을 작성하지 않아도하지만 난 단 하나의 일반적인 라우터가 :이 같은 서버에 예를 들어 인스턴스화 할 수 있습니다.

내 일반적인 라우터를 테스트하고 싶습니다하지만 몇 가지 문제를 참조하십시오

  1. 방법 "주입"앱을? Express (var app = express();)의 인스턴스를 만들 수 있지만 모의 테스트가 더 좋을 것이라고 생각합니다 (통합 테스트가 아닌 단위 테스트이므로!). 적절한 모의를하는 가장 좋은 방법은 무엇입니까?
  2. 정확히 테스트해야 할 사항은 무엇입니까? 내가보기에는 라우터 자체가 (통합없이) 다른 것을하지 않고 콘솔 출력 (테스트 할 가치가 없다)과 함수 호출 (controller.create(req, res);)을 수행한다. 이 함수가 호출되는지 어떻게 테스트해야합니까? 아니면 테스트 할 다른 것이 있습니까?

답변

0
  1. 당신은 아마 응용 프로그램의 스텁 구현을해야합니다.

  2. 테스트하려는 것은 생성자가 지정된 경로 + HTTP 메소드에 리스너를 등록한다는 것입니다. Sinon.js 스텁을 앱 스텁에 넣고 테스트에서 예상되는 인수로 호출되는지 확인하는 것이 좋습니다.

0
  1. 내가 응용 프로그램을 조롱 (아마도뿐만 아니라 컨트롤러)에 jasmine.createSpyObj를 사용합니다.
  2. 필자는 app.post가 '/ api /'+ resourceName 및 controller.create 인수를 사용하여 호출된다는 것을 테스트해야한다고 생각합니다. express.post가 올바르게 작동하는지 테스트하지 않았기 때문입니다.

다음 두 가지를 구체적으로 설명합니다.

내가 조금 router.js 수정할 것

를 만들려면이 쉽게 :

var Router = function(app, resourceName, controller) { 
    app.post('/api/' + resourceName, controller.create.bind(controller)) 
} 

module.exports = Router; 

그리고 테스트는 다음과 같이 보일 것이다 :

describe("Router", function() { 
    it("should route /api to controller.create", function() { 
    router = require('./router'); 
    app = jasmine.createSpyObj('application', ['post']); 
    controller = jasmine.createSpyObj('controller', ['create']); 
    router(app, 'foo', controller); 
    expect(app.post).toHaveBeenCalledWith('/api/foo', jasmine.any(Function)); 
    }); 
}); 

이 완벽한 테스트 때문에 아닙니다 실제로 controller.create가 호출되는지를 확인하고 있지 않습니다. 그것은 .bind() 물건 때문에 조금 더 복잡해집니다.

describe("Router", function() { 
    it("should route /api to controller.create", function() { 
    router = require('./router'); 
    app = jasmine.createSpyObj('application', ['post']); 
    controller = jasmine.createSpyObj('controller', ['create']); 
    controller.create = jasmine.createSpyObj('binder', ['bind']); 
    controller.create.bind.and.returnValue('bar'); 
    router(app, 'foo', controller); 
    expect(controller.create.bind).toHaveBeenCalledWith(controller); 
    expect(app.post).toHaveBeenCalledWith('/api/foo', controller.create.bind(controller)); 
    }); 
}); 
관련 문제