Reputation: 2697
I'm very new to Jasmine and ran across a situation where I would expect either a String or null. I attempted to do an or within the toEqual, but I'm seeing some odd results which leads me to believe I'm going about this the wrong way. What is the best way to go about a situation like this?
Perhaps I'm just going about my testing wrong. Should I just scrap this idea of having one test to test both situations?
describe("Jasmine", function () {
//1
it("should be able to handle any(String) || null within toEqual for string", function () {
expect("aString").toEqual(jasmine.any(String) || null);
});
//2
it("should be able to handle any(String) || null within toEqual for null", function () {
expect(null).toEqual(jasmine.any(String) || null);
});
//3
it("should be able to handle null || any(String) within toEqual for string", function () {
expect("aString").toEqual(null || jasmine.any(String));
});
//4
it("should be able to handle null || any(String) within toEqual for null", function () {
expect(null).toEqual(null || jasmine.any(String));
});
});
Expected null to equal <jasmine.any(function String() { [native code] })>.
Expected null to equal <jasmine.any(function String() { [native code] })>.
I realize there is also a toBeNull() which is probably why the results are so wonky, but without an "or" chaining I didn't know how to incorporate it.
(Running Jasmine 1.3.1 revision 1354556913)
Solved! Full solution below if anyone is interested
describe("Jasmine", function () {
beforeEach(function () {
this.addMatchers({
toBeStringOrNull: function () {
var actual = this.actual;
this.message = function () {
return "Expected " + actual + " to be either string or null";
};
return typeof actual === 'string' || actual instanceof String || actual === null;
}
});
});
//1
it("should be able to handle any(String) || null within toEqual for string", function () {
expect("aString").toBeStringOrNull();
});
//2
it("should be able to handle any(String) || null within toEqual for null", function () {
expect(null).toBeStringOrNull();
});
//3
it("should be able to handle null || any(String) within toEqual for string", function () {
expect("aString").toBeStringOrNull();
});
//4
it("should be able to handle null || any(String) within toEqual for null", function () {
expect(null).toBeStringOrNull();
});
});
Upvotes: 6
Views: 6801
Reputation: 8807
Write your own custom matcher:
toBeStringOrNull: function() {
var actual = this.actual;
this.message = function () {
return "Expected " + actual + " to be either string or null";
}
return typeof actual === 'string' || actual instanceof String || actual === null;
}
Upvotes: 12
Reputation: 440
Provided that you definitely want those cases to work on the same test, you could write your own matcher. Something like
toBeStringOrNull: function() {
var actual = this.actual;
this.message = function () {
return "Expected " + actual + " to be either string or null";
}
return jasmine.any(String) || actual === null;
}
Upvotes: 1