JavaScript JavaScript Unit Testing Improving Our Tests Catching an Error

Harold Stewart
Harold Stewart
9,322 Points

Javascript unit testing challenge

I must be misunderstanding the goal. I thought it was to write a test case that catched an expected error message. But when checking my work, I get the message " We tried your spec with a version of subtraction.js that DOESN'T work correctly, expecting the test to fail. But it passed! Better try again!". I though passing the test was to goal. Can someone help me understand to he goal of this challenge?

subtraction_spec.js
var expect = require('chai').expect

describe('subtraction', function () {
  var subtraction = require('../WHEREVER')  
  it('only works with numbers', function () {
   expect(subtraction("A","B").to.throw("subtraction only works with numbers!");
  })
})
subtraction.js
function subtraction (number1, number2) {
  if (typeof number1 !== 'number' || typeof number2 !== 'number') {
    throw Error('subtraction only works with numbers!')
  }
  return number1 - number2
}

2 Answers

Steven Parker
Steven Parker
207,988 Points

When used with "to.throw", the expect function takes another function as a parameter, not the result of calling one.
Also, you're a missing a close parenthesis before .to.throw.

But the main issue is the argument passed to expect. You could build a "handler" function and pass that as was done in the video example, or you could curry the arguments and pass the function using bind:

   expect(subtraction.bind(null,"A","B")).to.throw("subtraction only works with numbers!");
Sam Donald
Sam Donald
36,304 Points

To be clear expect will take the result of a called function.

But in this case with throw, it requires the use of a callback function.

Tom Geraghty
Tom Geraghty
24,159 Points

@Steven, I always appreciate your answers and reminding us of argument currying; I would not have been able to solve this challenge based on the lecture alone without your reminder that expect wants a function and not the result of the call of that function as it's parameter.

I also wanted to put up my answer that, I believe, demonstrates the same techniques used in the video lecture without confusing people who aren't as familiar with .bind() and currying parameters.

describe('subtraction', function () {
  var subtraction = require('../WHEREVER')  // anyone else find this confusing? I'd rather Treehouse just hid this or made it refer to the actual imported file's location (which I understand is difficult in Workspaces, but you guys are pros figure it out!)
  it('only works with numbers', function () {
    var handler = function(a,b) { subtraction(a,b) }
    expect(handler).to.throw(Error)
    expect(handler).to.throw('subtraction only works with numbers!')
  })
})

This will pass the test and matches with Guil's code from the videos/source project files.

Steven Parker
Steven Parker
207,988 Points

That was actually my first suggestion (though I didn't illustrate it), but don't you still need to call "subtraction" with defined non-numeric arguments for the test to work?