rayd
rayd

Reputation: 370

Component/Integration testing Backbone views and more

I'm looking to write some tests that test the wiring between Backbone views and their models. I essentially want to load up my view with a model and make sure everything is peachy (events properly triggered/handled, elements added to the DOM, etc). I see this as different from acceptance/functional/e2e testing, but larger than simple unit tests. In other words, I'm not looking to write:

var browser = new Browser()
  , fakeData = readFixtures("persons.json");

fakeAPIResponse('/persons', fakeData);

browser.visit("http://localhost:3000/", function () {
  assert.ok(browser.success);
  var persons = browser.queryAll(".persons li");
  assert.lengthOf(persons, 20);
});

but rather something like

var router = require('routers/main'),
    UserModel = require('models/user'),
    AccountView = require('views/account');
...
# In a test
var model = new UserModel({ userId: 1 });
router._showView(new AccountView({ model: model });
expect(document.getElementsByClassName('account-panel')).to.have.length(1);
model.set('name', 'Test Testerson');
expect(document.getElementById('name-field').value).to.equal('Test Testerson');

Maybe I'm way off and should just put together some end-to-end tests but this seems to me like it'd be a valuable way of testing. My question is: how can I accomplish this? I need a full DOM, so I'm thinking that these should run in something like PhantomJS; the DOM should be reset before each test, but it seems silly/inefficient to have the browser navigate to a new page for each individual test. Is there a framework out there for running a test this way? Feel free to tell me I'm wrong for wanting this.

Upvotes: 1

Views: 261

Answers (1)

What have you tried
What have you tried

Reputation: 11148

We are doing this using casperJs. Casper will give you the full DOM, but this should not be the reason the choose integration test over unit test. When I find myself going way out of my way to create a test environment, I tend to choose integration.

However, having said that, I think you can get away with doing a unit test and here is how I would do it. We are using testem with chaiJs assertions for such tests. If you setup a fixture, you can do something like this (and you'll have the full DOM, and ability to test events and everything else listed in your OP).

beforeEach(function () {
    var theModel = new Backbone.Model(),
        theViewToTest = new TheViewToTest({
            model: theModel,
            el: $(fixtures.get('some-fixture.html'))
        });

    theViewToTest.render();

    this.theViewToTest = theViewToTest;

});

describe('Checking event handlers', function () {
    it('Should fire some events', function () {

        // I would setup a spy here and listen to the button handler
        this.theViewToTest.$el.find('.some-button').trigger('click');

        // Assert the spy was called once


    });
});

Upvotes: 1

Related Questions