4
\$\begingroup\$

I'm learning backbone.js in parallel with unit testing. I've just made a simple model and wanted to unit test it. Do I have the right idea? I am simply making a model with some default values.

Person = Backbone.Model.extend({
defaults: { 
    name: "fetus",
    age: 0, 
    child: ''
},

initialize: function() {
    console.log("Welcome to this world"); 
}
}); 



var test_Person = {}; 

var test_Person.Defaults = function() {
    var person = new Person(); 

    person.assertString(person.defaults.initialize,"Welcome to this world");
    person.assertString(person.defaults.name,"fetus");
    person.assertNum(person.defaults.age,0);
    person.assertString(person.defaults.child,"");
}(); 
\$\endgroup\$
  • \$\begingroup\$ I think that it's an awesome approach to learning Backbone, that is, to learn how to unit test it simultaneously as you learn it. Now, to take a step back, I don't think that you need to unit test this code. Why? Because having Backbone set some values to defaults is something that cannot go wrong. If you unit test that Backbone set the defaults then you are repeating yourself, you're just hardcoding the values in your unit test, too. IMHO, logic deserves unit tests. As an example, you can look at my post: codereview.stackexchange.com/questions/61629/… \$\endgroup\$ – SBel Aug 31 '14 at 17:24
3
\$\begingroup\$

If your Person was initialized with a name other than "fetus", your test would fail.. but your test has several reasons for failing and that's what makes it not-so-good: that same test would also fail if a Person was "born" with a child (!) or if age defaulted to 1, or if the welcome to this world string was different.

I've never written a unit test with JS, but I believe the following would apply:

  • Name your test method so that anybody (including non-technical) reading it (the name) knows exactly what is being tested.
  • Arrange the dependencies of your SUT (that's System Under Test). Set up /configure your mocks, define what the expected outcome should be.
  • Act upon your SUT (i.e. call the method you want to test). Pass in your mock dependencies, retrieve the "actual" result.
  • Assert - verify that you get expected results, i.e. make the test pass, or fail.

In this particular case, I'm not sure what's being tested exactly - you're merely verifying that the person object was initialized with the expected default values? I guess it's ok.

Unit tests should be testing that the code does what it's supposed to be doing.

As I said I've never written a test with JS, so this example is C#:

    [TestMethod]
    public void ShouldReplaceCommaWithEmptyStringInProductDescription()
    {
        // arrange
        var testDescription = "Product,Description";
        var data = GetValidMockRecord();
        var values = data.Split(',');
        values[11] = testDescription;
        data = string.Join(",", values);

        if (!testDescription.Contains(",")) Assert.Inconclusive("testDescription must contain at least one (1) comma (,).");

        var sut = new EdiParser();
        var expected = testDescription.Replace(",", string.Empty);

        // act
        var result = sut.Parse(data);
        var actual = result.ProductDescription;

        // assert
        Assert.AreEqual(expected, actual);
    }

I don't think the language is a barrier: as you can see I'm asserting in my arrange section and making the test inconclusive if the test data would make the test, well, inconclusive. Then in the actual assert section I'm only testing one thing, and this is what unit testing is really about.

\$\endgroup\$
  • \$\begingroup\$ Thanks this is really good information. So do you agree that my example does not really require a unit test. I mean the defaults are pretty obvious from looking at the code. Unless I said that the person object was supposed to be initialized with those exact default values, then I would have to write a unit test for that. Ah, now this is where unit testing starts to get confusing. So I guess it comes down to requirements with unit testing, I was reading up on TDD and that gave me the impression to unit test pretty much every function/object you write \$\endgroup\$ – user2202911 Nov 15 '13 at 16:28
  • \$\begingroup\$ I'm not much into TDD so maybe you read and understand the right thing. IMHO unit tests aim at protecting your program's logic against changes - let me explain: if changing the default value for a person's age from 0 to 1 could break something somewhere, then yes you should have a unit test that verifies that every person is initialized with an age of 0. But most of your tests should cover methods that implement some logic. Also make sure your tests are shielded from each other (they should be able to run independently, in any order). \$\endgroup\$ – Mathieu Guindon Nov 15 '13 at 16:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.