Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to check against multiple types within a toEqual in Jasmine.Js?

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));
    });
});
  1. Pass
  2. Expected null to equal <jasmine.any(function String() { [native code] })>.
  3. Pass
  4. 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();
    });
});
like image 665
JackMorrissey Avatar asked Feb 22 '13 17:02

JackMorrissey


People also ask

How do you compare objects in Jasmine?

You are trying to compare two different instances of an object which is true for regular equality ( a == b ) but not true for strict equality ( a === b). The comparator that jasmine uses is jasmine. Env. equals_() which looks for strict equality.

What is the difference between toBe and toEqual in Jasmine?

in a nutshell: no difference between the two when comparing primitives; for objects -> toEqual() will compare by key/values-content; toBe() will compare by object reference.

Which matcher is used in Jasmine to check whether the result is equal to true or false?

ToBeTruthy() This Boolean matcher is used in Jasmine to check whether the result is equal to true or false. The following example will help us understand the working principle of the toBeTruthy() function.

Which of the following Jasmine matchers can be used to check for a regular expression?

It checks whether something is matched for a regular expression. You can use the toMatch matcher to test search patterns.


2 Answers

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;
}
like image 152
tekumara Avatar answered Oct 28 '22 00:10

tekumara


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;
}
like image 25
Felipe Avatar answered Oct 27 '22 22:10

Felipe