Asserting throws in tape - node
Asked Answered
O

1

6

So I am trying to test out a function, it is a client-side function(un-finish) which is why it is embedded in the test itself(until I can figure out a better solution).

The problem I am having is when I test to see if the function is throwing a TypeError.

I understand the problem is because it is testing the return value and not the function itself, I am unsure how to work around this.

Any and All help is appreciated!

Tape


test.js

var test  = require('tape');


test('GenerateRandomNumber Tests', function(assert){  

  /**
   * Generates a random number between the min/max
   * @param {int} the min value 
   * @param {int} the max value 
   * @param {array} list of values already stored
   * @return {mixed} int if success, false if exception thrown
  **/
  var GenerateRandomNumber = function( min, max, tickets ){
        
    try{
      
      if(!tickets instanceof Array){
        throw new TypeError();
      }
      
      min = (min) || 0;
      max = (max) || 200;
      
      var n = 0;

      n = ~~(Math.random() * (max - min) + min); 
      
      if(tickets.indexOf(n) === 1){
        GenerateRandomNumber(min, max);
      }
      
      return n;
      
    }catch(e){ return false; } 
    
  };
  
  assert.plan(4);
  
  
  var t1 = GenerateRandomNumber(0, 300, null);
  assert.equal(typeof t1, "boolean", "Should return a boolean - false");
  
  var t2 = GenerateRandomNumber(0, 300, [0,1,2,3,4]);
  assert.equal(typeof t2, "number", "Should return a typeof number");
  
  // HELP
  assert.throws(GenerateRandomNumber(0, 300, null), TypeError, "Should throw typeError");
  
  var t4 = GenerateRandomNumber(null, null, [0,1,2,3,4]);
  assert.equal(typeof t4, "number", "Should return a typeof number");
  
  
});
Odericus answered 7/12, 2015 at 19:55 Comment(4)
tape-catch might help? link: npmjs.com/package/tape-catchChian
I will look into that, thank you @JamesonYuOdericus
What exactly are you expecting to happen? I ran this and all the tests passed. Are you expecting assert.throws to fail?Multifoliate
If you comment out throw new TypeError, the tests will still pass. which is not the desired behavior. I'm sure the assert.throws method is evaluating the return value and not evaluating the function itself. @cojomojoOdericus
M
9

Well you're first problem is that !tickets instanceof Array is not the logic you want. What that does is first executes the not operation on tickets and then tests if that is an instanceof Array. So what you actually want is:

if(!(tickets instanceof Array)){
   throw new TypeError();
}

The next issue is that, like you said, you are getting the return value of GenerateRandomNumber, which if an error is thrown, is false not a TypeError. If you want to keep your try/catch and return false in GenerateRandomNumber then you don't need the throws test but rather something like:

assert.equal(GenerateRandomNumber(0, 300, null), false, "Should catch the TypeError and return false)

If you want to use assert.throws then you need to remove the try/catch from GenerateRandomNumber and instead do something like this:

var test  = require('tape');


test('GenerateRandomNumber Tests', function(assert){  

  /**
   * Generates a random number between the min/max
   * @param {int} the min value 
   * @param {int} the max value 
   * @param {array} list of values already stored
   * @return {mixed} int if success, false if exception thrown
  **/
  var GenerateRandomNumber = function( min, max, tickets ){
      if(!(tickets instanceof Array)){
        throw new TypeError('error');
      }

      min = (min) || 0;
      max = (max) || 200;

      var n = 0;

      n = ~~(Math.random() * (max - min) + min); 

      if(tickets.indexOf(n) === 1){
        GenerateRandomNumber(min, max);
      }

      return n;
  };

  assert.plan(3);

  var t2 = GenerateRandomNumber(0, 300, [0,1,2,3,4]);
  assert.equal(typeof t2, "number", "Should return a typeof number");

  // You must wrap GenerateRandomNumber from within another function 
  //so that the error being thrown doesn't cause the program to exit
  assert.throws(() => GenerateRandomNumber(0, 300, null), /error/, "Should throw typeError");

  var t4 = GenerateRandomNumber(null, null, [0,1,2,3,4]);
  assert.equal(typeof t4, "number", "Should return a typeof number");


});

I used the option to pass a RegExp because tape's matching of errors when passing a function as expected is quite strange (see this issue). Im looking into an option for doing it this way still, but hopefully this helps you for now.

Multifoliate answered 7/12, 2015 at 20:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.