Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to expose javascript objects for unit testing without polluting the global namespace

I have a javascript autocomplete plugin that uses the following classes (written in coffeescript): Query, Suggestion, SuggestionCollection, and Autocomplete. Each of these classes has an associated spec written in Jasmine.

The plugin is defined within a module, e.g.:

(function(){
  // plugin...
}).call(this);

This prevents the classes from polluting the global namespace, but also hides them from any tests (specs with jasmine, or unit-tests with something like q-unit).

What is the best way to expose javascript classes or objects for testing without polluting the global namespace?

I'll answer with the solution I came up with, but I'm hoping that there is something more standard.

Update: My Attempted Solution

Because I'm a newb with < 100 xp, I can't answer my own question for 8 hours. Instead of waiting I'll just add what I did here.

In order to spec these classes, I invented a global object called _test that I exposed all the classes within for testing. For example, in coffeescript:

class Query
  // ...

class Suggestion
  // ...

// Use the classes

// Expose the classes for testing
window._test = {
  Query: Query
  Suggestion: Suggestion
}

Inside my specs, then, I can reveal the class I'm testing:

Query = window._test.Query

describe 'Query', ->
  // ...

This has the advantage that only the _test object is polluted, and it is unlikely it will collide with another definition of this object. It is still not as clean as I would like it, though. I'm hoping someone will provide a better solution.

like image 568
Mitch Avatar asked Dec 20 '11 01:12

Mitch


1 Answers

I think something like the CommonJS module system (as used by brunch, for example) would work.

You can separate your code into modules, and the parts that need them would import them via require. The only part that gets "polluted" is the module map maintained by the module management code, very similar to your test object.

In Autocomplete.coffee

class exports.Query
// ...

class exports.Suggestion
// ...

and then in Autocomplete.spec.coffee

{Query, Suggestion} = require 'app/models/Autocomplete'

describe 'Query', ->
like image 74
Thilo Avatar answered Oct 19 '22 07:10

Thilo