E57 XC: Experience testing BowFolios

BowFolios is an application designed to help you build your first Meteor application by providing examples of useful design patterns.

In this extra credit experience, you will write two more tests for BowFolios using Mocha and Chai in order to better understand how to unit test the data model for a Meteor application.

Prerequisites

Prior to starting this WOD, please:

How to test that a function throws an error

For this WOD, you will write two new unit tests for BowFolios to better verify the functioning of the ProfileCollection. Both of these tests check to see that the ProfileCollection define() method throws an error when passed inappropriate arguments. In Chai, checking to see that a function throws an error requires a slightly unintuitive calling structure. Under normal circumstances, Chai assertions look something like this:

expect(foo('bar')).to.be.true;

This checks, obviously enough, that foo(‘bar’) returns true.

Now, let’s say that we instead want to check that foo(‘bar’) throws an error. We might be tempted to write this:

expect(foo('bar')).to.throw(Error);

That won’t work correctly. The reason is that foo(‘bar’) will be invoked and the error thrown before the expect() function is invoked, which means the expect() function will never even see the results of invoking foo(‘bar’). The solution is to pass expect() a function that invokes foo(‘bar’). That way, expect() can invoke the function and trap the results. So, whenever you are testing to see that a function throws an error, you need to wrap that call in a new function and pass that into expect(). Here’s the correct way to do it:

expect(function() { foo('bar'); }).to.throw(Error);

Hints on using Mocha

When you are in the process of developing tests with Mocha, occasionally you can get Mocha into a state where it reports a test failure even though the test code is correct.

If you feel that your test case is correct even though Mocha is reporting an error, try exiting the test process, running meteor reset, and then restarting your tests with meteor npm run test-watch.

If an error is still reported, then it’s most likely your code that’s the problem, not Mocha.

The WOD

Ready? Let’s begin:

  1. Start your timer.

  2. Create a branch of your BowFolios repo called “testing-1”. All your work for this WOD will be done in that branch.

  3. Review the code for the ProfileCollection.define() function in imports/api/profile/ProfileCollection.js. You can see that an error is thrown if the define() function is passed an undefined interest. Unfortunately, this constraint is never tested in ProfileCollection.test.js (located in the same directory).

  4. Add a unit test to check that the ProfileCollection.define() method throws an error when passed an illegal (i.e. undefined) interest. To help you understand how this works, here’s one way to write this unit test:

    it('#define (illegal interest)', function test() {
      const illegalInterests = ['foo'];
      const username2 = 'philipmjohnson';
      const defineObject2 = { firstName, lastName, username2, bio, illegalInterests, picture, title,
        github, facebook, instagram };
      expect(function foo() { Profiles.define(defineObject2); }).to.throw(Error);
     });
    
  5. Run the unit tests for BowFolios to verify that this test is invoked and passes.

  6. Now that you’re warmed up, here’s a slightly harder task. It makes no sense to pass a list of Interests to the ProfileCollection.define() method that contains duplicates. However, the ProfileCollection.define() method does not check to see that the list of Interests does not contain any duplicates. For this part of the WOD, please: (1) enhance the ProfileCollection.define() method to throw an error if the passed list of Interests contains any duplicates, and (2) write a unit test to verify that an error will be thrown if ProfileCollection.define() is called with a list containing duplicate Interests.

  7. Run the unit tests for BowFolios to verify that this test is invoked and passes.

  8. Commit your branch to GitHub.

  9. Stop your timer and record your time.

Rx: < 20 min Av: 20-25 min Sd: 25-30 min DNF: 30+ min

Demonstration

As this is extra credit, I’m not going to provide a YouTube video of the solution, but instead encourage you to watch the screencast and play around until you can get the tests to run successfully. For example, here’s what my Mocha test.html file produces:

Submission Instructions

To be completed by the time and date indicated on the Schedule page. Submit the URL to your GitHub repo to Laulima to get credit.