title: Mocha unit tests running with Karma - done() is not defined
body: <p>I'm trying to get tests written with Mocha to work running Karma, and they sort of work, but I cannot use the done() method to implement async tests, which essentially makes the tools useless to me. What am I missing?</p>
  
  <p>karma.conf.js</p>
  
  <pre><code>module.exports = function(config) {
    config.set({
      basePath: '../..',
      frameworks: ['mocha', 'requirejs', 'qunit'],
      client: {
          mocha: {
              ui: 'bdd'
          }
      },
      files: [
        {pattern: 'libs/**/*.js', included: false},
        {pattern: 'src/**/*.js', included: false},
        {pattern: 'tests/mocha/mocha.js', included: false},
        {pattern: 'tests/should/should.js', included: false},
        {pattern: 'tests/**/*Spec.js', included: false},
        'tests/karma/test-main.js'
      ],
      exclude: [
        'src/main.js'
      ],
      // test results reporter to use
      // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
      reporters: ['progress', 'dots'],
      port: 9876,
      colors: true,
      // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
      logLevel: config.LOG_WARN,
      autoWatch: true,
      // Start these browsers, currently available:
      // - Chrome
      // - ChromeCanary
      // - Firefox
      // - Opera (has to be installed with `npm install karma-opera-launcher`)
      // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
      // - PhantomJS
      // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
      browsers: ['Chrome'],
      // If browser does not capture in given timeout [ms], kill it
      captureTimeout: 60000,
      // Continuous Integration mode
      // if true, it capture browsers, run tests and exit
      singleRun: false
    });
  };
  </code></pre>
  
  <p>test-main.js (configuring RequireJS)</p>
  
  <pre><code>var allTestFiles = [];
  var pathToModule = function(path) {
    return path.replace(/^\/base\//, '../').replace(/\.js$/, '');
  };
  
  Object.keys(window.__karma__.files).forEach(function(file) {
    if (/Spec\.js$/.test(file)) {
      // Normalize paths to RequireJS module names.
      allTestFiles.push(pathToModule(file));
    }
  });
  
  require.config({
    // Karma serves files under /base, which is the basePath from your config file
    baseUrl: '/base/src',
    paths: {
      'should': '../tests/should/should',
      'mocha': '../tests/mocha/mocha',
      'pubsub': '../libs/pubsub/pubsub',
      'jquery': '../libs/jquery/jquery-1.10.2',
      'jquery-mobile': '//code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min'
    },
    // dynamically load all test files
    deps: allTestFiles, 
    // we have to kickoff jasmine, as it is asynchronous
    callback: window.__karma__.start
  });
  </code></pre>
  
  <p>tests/fooSpec.js</p>
  
  <pre><code>define(['music/note'], function(Note) {
  
  describe('nothing', function(done) {
      it('a silly test', function() {
          var note = new Note;
          note.should.not.eql(32);
      });
      done();
  });
  ...
  </code></pre>
  
  <p>Though this is a contrived example, it succeeds if I remove the done() call. As it is, I get:</p>
  
  <pre><code>Uncaught TypeError: undefined is not a function
  at /Library/WebServer/Documents/vg/tests/mocha/fooSpec.js:8
  </code></pre>
  
  <p>This is the done() line. How/why is this not defined? I'm not understanding where else to configure Mocha (or with what options). Is there some sort of global namespace or meta-programming magic causing RequireJS to interfere with Mocha?</p>
  
  <p>I'm running the tests in Chrome 33 on OS X 10.9.2, in case that is at all relevant. I've killed a ton of time on this and am ready to give up on automated testing :( -- had similar brick walls with QUnit/Karma/RequireJS and have not been able to find any alternative to successfully automate tests. I feel like an idiot. </p>