title: How to test promises in Mongo(ose)/Express app?
body: <p>I'm using promises to wrap asynchronous (Mongo) DB ops at the end of an (expressJS) route. 
  I want to try and figure out how to test the following code.</p>
  
  <p><strong>userService</strong></p>
  
  <pre><code>userService.findOne = function (id) {
  
      var deferred = q.defer();
  
      User.findOne({"_id" : id})
          .exec(function (error, user) {
              if (error) {
                  deferred.reject(error);
              } else {
                  deferred.resolve(user);
              }
          });
  
      return deferred.promise;
  };
  </code></pre>
  
  <p><strong>userRoute</strong></p>
  
  <pre><code>var user = function (req, res) {
      var userId = req.params.id
           , userService = req.load("userService");
           // custom middleware that enables me to inject mocks
  
      return userService.findOne(id)
          .then(function (user) {
              console.log("called then");
              res.json({
                  msg: "foo"
              });
          }).catch(function (error) {
              console.log("called catch");
              res.json({
                  error: error
              });
          }).done();
  };
  </code></pre>
  
  <p>Here's an attempt to test the above with mocha</p>
  
  <p><strong>userTest</strong></p>
  
  <pre><code>it("when resolved", function (done) {
  
      var jsonSpy = sinon.spy(httpMock.res, "json")
          , httpMock = require("/path/to/mock/http/object")
          , serviceMock = require("/path/to/mock/service"),
          , deferred = q.defer()
          , findStub = sinon.stub(serviceMock, "findOne")
              .returns(deferred.promise)
          , loadStub = sinon.stub(httpMock.req, "load")
              .returns(serviceMock),
          retPromise;
  
  
      // trigger route
      routes.user(httpMock.req, httpMock.res);
  
      // force promise to resolve?
      deferred.resolve(); 
  
      expect(jsonSpy.called).to.be.true; // fails
  
      // chai as promised 
      retPromise = findStub.returnValues[0];
      expect(retPromise).to.be.fulfilled; // passes
  });
  </code></pre>
  
  <p>the http mock is just an empty object with no-ops where expressJS would normally start rendering stuff. I've added some logging inside those no-ops to get an idea on how this is hanging together.</p>
  
  <p>This isn't really working out. I want to verify how the whole is integrated, to establish some sort of regression suite - but I've effectively mocked it to smithereens and I'm just testing my mocks (not entirely successfully at that).</p>
  
  <p>I'm also noticing that the console logs inside my http mocks triggered by then and catch are firing twice - but the jsonSpy that is invoked inside the actual code (verified by logging out the sinon spy within the userRoute code) is not called in test.</p>
  
  <p>Has anyone got some advice on integration testing strategies for express apps backed by Mongo?</p>