Andrew Schools
Andrew Schools

Reputation: 321

Dependency injection in JavaScript using apply, call or bind methods

I'm fairly new to JavaScript and have a question about unit-testing an object and it's methods. Is using the JavaScript bind, apply and call methods considered a form of dependency injection? I ask because I have several functions I want to unit-test that use the 'this' keyword and I would like to set the context of those functions before running a test. Should I call the constructor with the appropriate parameters and then unit-test those methods or could I use one of the apply, call or bind methods? Example provided below:

function assert(v1, v2) {
  console.log(v1 === v2);
}

function User(firstName, lastName, identifier) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.identifier = identifier;
}

User.prototype.getUserString = function() {
  return this.lastName + ", " + this.firstName + " <" + this.identifier + ">";
}

// First option:

var user = new User('Andrew', 'Schools', '09AF22');
assert(user.getUserString(), 'Schools, Andrew <09AF22>');

// Second option:

var getUserString = User.prototype.getUserString.bind({
  'lastName': 'Schools',
  'firstName': 'Andrew',
  'identifier': '09AF22'
});

assert(getUserString(), 'Schools, Andrew <09AF22>');

My concern with option one is that the own properties can be changed by other methods after they are invoked thus failing my tests. I guess I could always reset the variables before every test but that's extra work, especially if the object has many own properties. Is there any issues with using the apply, call or bind methods when unit-testing?

Upvotes: 0

Views: 395

Answers (1)

Kirill Slatin
Kirill Slatin

Reputation: 6143

I guess I could always reset the variables before every test but that's extra work, especially if the object has many own properties.

Actually this is not very difficult. For the sake of you test suite you define methods that create a set of objects and mocks for testing. And you reset your object before each test.

var user;
function prepare(){
    user = new User('Andrew', 'Schools', '09AF22');
}

prepare();
assert(test1);
prepare();
assert(test2);

That is why testing frameworks like karma, mocha have beforeEach methods which allows to reset environment before each unit test. Because each unit test should not depend on results of another unit test.

Upvotes: 2

Related Questions