title: Mixing sync and async tests using Mocha
body: <p>I have a function, which computes some stuff, notifying the user via callbacks about some events:</p>
  
  <pre><code>function returnAndCallback(callback) {
    callback(5);  // not always invoked
    return 3;
  }
  </code></pre>
  
  <p>Using Mocha and Should.js, I wrote this test:</p>
  
  <pre><code>describe('mixing sync and async code', function() {
    it('should test callback AND return value', function(done) {
      returnAndCallback(function(value) {
        value.should.be.eql(5);
        done();
      }).should.be.eql(4);
    });
  });
  </code></pre>
  
  <p>This succeeds because the test ends when <code>done()</code> is called. It seems, I can either write a synchronous test and check the return value, or I can write an asynchronous test and check the callback.</p>
  
  <p>One can not use a sync test like this: </p>
  
  <pre><code>describe('mixing sync and async code', function() {
    it('should test callback AND return value', function() {
      returnAndCallback(function(value) {
        should.be.eql('difficult to get result');
      }).should.be.eql(3);
    });
  });
  </code></pre>
  
  <p>... because I want to assert that the callback is called. This test would succeed, if the callback is never called.</p>
  
  <p>How can I test both that the callback is called with the right value <strong>AND</strong> the correct value is returned?</p>
  
  <p>Duplicating tests is the only option I see.</p>
  
  <p><strong>Edit:</strong> I notice, that I use the term asynchron wrongly here. The callbacks are merely a way to inject optional actions into a function, which transforms an object. All code is synchronous, but the control flow sometimes branches of into callbacks and I want to be able to recognize that.</p>
  
  <p>Here is another possible way to test that:</p>
  
  <pre><code>describe('mixing sync and async code', function() {
    it('should test callback AND return value', function() {
      let callbackValue;
  
      returnAndCallback(function(value) {
        callbackValue = value;
      }).should.be.eql(3);
  
      callbackValue.should.be.eql(5);
    });
  });
  </code></pre>
  
  <p>But still not perfectly elegant due to the extra variable.</p>