This example shows how to use the Assert.throwsError()
method to detect when certain functions will throw errors. This functionality replaces the _should.error
options in previous YUI Test versions.
The first method shows simple error detection with a test that simply throws an error:
var throwErrorsTestCase = new YUITest.TestCase({
//the name of the test case - if not provided, one is automatically generated
name: "Throwing Errors Tests",
...
testGenericError : function() {
/*
* You can specify a constructor for an error. All native errors
* inherit from Error, so this effectively tests for all native
* error types.
*/
YUITest.Assert.throwsError(Error, function(){
throw new Error("Generic error");
});
},
...
});
The fact that this method throws an error that is of type Error
is enough to cause it to pass (the message doesn't matter). The next
two methods, testStringError()
and testStringError2()
are specified as throwing an error with a specific
message ("I'm a specific error message."):
var throwErrorsTestCase = new YUITest.TestCase({
//the name of the test case - if not provided, one is automatically generated
name: "Throwing Errors Tests",
...
testStringError : function() {
/*
* You can specify an error message, in which case the test passes only
* if the error thrown matches the given message.
*/
YUITest.Assert.throwsError("I'm a specific error message.", function(){
throw new Error("I'm a specific error message.");
});
},
testStringError2 : function() {
//throw a specific error message - this will fail because the message isn't expected
YUITest.Assert.throwsError("I'm a specific error message.", function(){
throw new Error("I'm a specific error message, but a wrong one.");
});
},
...
});
The testStringError()
method will pass when executed because the error message matches up exactly with the one
specified using YUITest.Assert.throwsError()
. The testStringError2()
method, however, will fail because its
error message is different from the one specified.
To be more specific, testObjectError()
, testObjectError2()
, and testObjectError3()
,
specified an error type (TypeError
) and an error messsage ("Number expected."):
var throwErrorsTestCase = new YUITest.TestCase({
//the name of the test case - if not provided, one is automatically generated
name: "Throwing Errors Tests",
...
testObjectError : function() {
/*
* You can also specify an error object, in which case the test passes only
* if the error thrown is on the same type and has the same message.
*/
YUITest.Assert.throwsError(new TypeError("Number expected."), function(){
throw new TypeError("Number expected.");
});
},
testObjectError2 : function() {
//throw a specific error and message - this will fail because the type doesn't match
YUITest.Assert.throwsError(new Error("Number expected."), function(){
throw new TypeError("Number expected.");
});
},
testObjectError3 : function() {
//throw a specific error and message - this will fail because the message doesn't match
YUITest.Assert.throwsError(new TypeError("Number expected."), function(){
throw new TypeError("String expected.");
});
}
});
Of the these three methods, only testObjectError()
will pass because it's the only one that throws a TypeError
object with the message, "Number expected." The testObjectError2()
method will fail because the type of error
being thrown (Error
) is different from the expected type (TypeError
), as specified using YUITest.Assert.throwsError()
.
The last method, testObjectError3()
, also fails. Though it throws the right type of error, the error message
doesn't match the one that was specified.
Since the standalone YUI Test library isn't a graphical library, you'll need to use something to visualize the results. This example uses a YUI 3 Console
object. To output the appropriate information into the console, a function is created to handle TestRunner
events:
//function to handle events generated by the testrunner
var TestRunner = YUITest.TestRunner;
function logEvent(event){
//data variables
var message = "",
messageType = "";
switch(event.type){
case TestRunner.BEGIN_EVENT:
message = "Testing began at " + (new Date()).toString() + ".";
messageType = "info";
break;
case TestRunner.COMPLETE_EVENT:
message = Y.substitute("Testing completed at " +
(new Date()).toString() + ".\n" +
"Passed:{passed} Failed:{failed} " +
"Total:{total} ({ignored} ignored)",
event.results);
messageType = "info";
break;
case TestRunner.TEST_FAIL_EVENT:
message = event.testName + ": failed.\n" + event.error.getMessage();
messageType = "fail";
break;
case TestRunner.TEST_IGNORE_EVENT:
message = event.testName + ": ignored.";
messageType = "ignore";
break;
case TestRunner.TEST_PASS_EVENT:
message = event.testName + ": passed.";
messageType = "pass";
break;
case TestRunner.TEST_SUITE_BEGIN_EVENT:
message = "Test suite \"" + event.testSuite.name + "\" started.";
messageType = "info";
break;
case TestRunner.TEST_SUITE_COMPLETE_EVENT:
message = Y.substitute("Test suite \"" +
event.testSuite.name + "\" completed" + ".\n" +
"Passed:{passed} Failed:{failed} " +
"Total:{total} ({ignored} ignored)",
event.results);
messageType = "info";
break;
case TestRunner.TEST_CASE_BEGIN_EVENT:
message = "Test case \"" + event.testCase.name + "\" started.";
messageType = "info";
break;
case TestRunner.TEST_CASE_COMPLETE_EVENT:
message = Y.substitute("Test case \"" +
event.testCase.name + "\" completed.\n" +
"Passed:{passed} Failed:{failed} " +
"Total:{total} ({ignored} ignored)",
event.results);
messageType = "info";
break;
default:
message = "Unexpected event " + event.type;
message = "info";
}
//only log if required
Y.log(message, messageType, "TestRunner");
}
//listen for events to publish to the logger
TestRunner.attach(TestRunner.BEGIN_EVENT, logEvent);
TestRunner.attach(TestRunner.COMPLETE_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_CASE_BEGIN_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_CASE_COMPLETE_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_SUITE_BEGIN_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_SUITE_COMPLETE_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_PASS_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_FAIL_EVENT, logEvent);
TestRunner.attach(TestRunner.TEST_IGNORE_EVENT, logEvent);
The logEvent()
function is used to handle all events. Based on the event, the message and the message type are determined and then a message is logged. This event handler is assigned to the TestRunner
events by using the attach()
method.
With all of the tests defined, the last step is to run them. This initialization is assigned to take place when all of the YUI components have been loaded:
//create the console
var r = new Y.Console({
verbose : true,
newestOnTop : false
});
r.render('#testLogger');
TestRunner.add(throwErrorsTestCase);
//run the tests
TestRunner.run();
Before running the tests, it's necessary to create a Y.Console
object to display the results (otherwise the tests would run
but you wouldn't see the results). After that, the YUITest.TestRunner
is loaded with the YUITest.TestSuite
object by calling
add()
(any number of YUITest.TestCase
and YUITest.TestSuite
objects can be added to a YUITest.TestRunner
,
this example only adds one for simplicity). The very last step is to call run()
, which begins executing the tests in its
queue and displays the results in the Y.Console
.