Takes function and throws exception if passed function doesn't throw an exception The code below is part of a toy test assertion library I've written.  

I'm looking for feedback specifically on lines 4 - 9.  I'd like to extract them from the throws function.  I can think of two options.


Create a function with a name like maybeReportExceptionError().  This seems not great because a) it feels like the function has two responsibilities and b) the maybe in the name seems hard to understand for someone not familiar with the inner workings of the function.
Replace the if/else if with a polymorphism.  I'm not sure how to go about this.


Any thoughts greatly appreciated!

function throws(testFunction, expectedMessage) {
  var thrownMessage = getFunctionExceptionMessage(testFunction);

  if (thrownMessage === undefined) {
    throw new Error("Expected an exception");
  } else if (thrownMessage !== expectedMessage) {
    throw new Error("Threw - " + thrownMessage + " - not - " + expectedMessage);
  }
};

function getFunctionExceptionMessage(fn) {
  try {
    fn();
  } catch (exception) {
    return exception.message;
  }
};

// USAGE:

// Throws "Error: Expected an exception"
throws(function() {

}, "Expected message");

// Throws "Error: Threw - Thrown message - not - Expected message"
throws(function() {
  throw new Error("Thrown message");
}, "Expected message");
It kind of boils down to coding style, but this is how I'd refactor your code.


I like my assertions to clearly state they are; rename throws() to assertThrows().
I like guard clauses rather than "unneccessary" else statements.
If a function ever throws an exception with an undefined message, your assertion would fail.
I like a specific format of assert failures: expected xxx but got yyy.


Code:

function assertThrows(testFunction, expectedMessage) {

    var actual = catchExceptionFrom(testFunction); 

    if (actual === undefined)
        throw new Error("Function did not throw an exception.");

    if (actual.message !== expectedMessage)
        throw new Error("Expected exception '" + expectedMessage + "' but got '" + actual.message + "'");
}; 

function catchExceptionFrom(fn) { 
    try { 
        fn(); 
    } 
    catch (exception) { 
        return exception; 
    } 
};