Search code examples
javascriptunit-testingqunit

Comparing Two Objects QUnit Javascript


I need to compare the properties of two objects and the property type, but not the values just the type.

So I have var a = {key1 : [], key2: { key3 : '' } }

And I want to compare that to another obejct I get back from a web service call.

In this case, the response is equal to {key1 : '', key2: { key3 : '' }, key4: 1 }

I try to do propEqual()

 assert.propEqual(response, a, "They are the same!");

This does the testing of the properties I believe, but it is also testing the value of the properties. I do not care about the value, I just want to test the overall structure and type.

So giving the above data examples, the test should throw 2 errors. One would be that, the key1 in the response is a string and I was expecting an array and the other would be that response has a key that is not expected (key4).

Is this possible? Thanks!!


Solution

  • You'll need to use your own logic to test what you are looking for. There are pretty much two things to test - types matching, and the number of properties in the response needing to match your object. I defined two functions, testTypesEqual (returns true if types match) and testPropertiesMatch (returns true if response has the same properties as your object). You'll need to use these (or a variation of these depending on your exact needs) in your tests. A full example can be found here http://jsfiddle.net/17sb921s/.

    //Tests that the response object contains the same properties 
    function testPropertiesMatch(yours, response){
        //If property count doesn't match, test failed
        if(Object.keys(yours).length !== Object.keys(response).length){
            return false;
        }
    
        //Loop through each property in your obj, and make sure
        //the resposne also has it.
        for(var prop in yours){
            if(!response.hasOwnProperty(prop)){
                //fail if response is missing a property found in your object
                return false;
            }
        }
    
        return true;
    }
    
    //Test that property types are equal
    function testTypesEqual(yours, response){
        return typeof(yours) === typeof(response)
    }
    

    You'll have to write one assert.ok per property you want to check for type mismatches. Finally, you'll have a single assert.ok checking that the properties in the response match those in your object.

    Example:

    //fails for key1
    assert.ok(testTypesEqual(a.key1, response.key1), "Will fail - key1 property types do not match");
    
    //fails - response contains additional property
    assert.ok(testPropertiesMatch(a, response), "Additional Properties - Fail due to additional prop in Response");
    

    Obviously now I have introduced new & non-trivial logic into your unit tests, the sole purpose of this answer is to show you how to do it, not to advise you to take complicated logic from a stranger and stick that all over your unit tests :).