0
votes

I am testing whether or not an array is what I expect it to be using toBe(). It passes with toEqual(), but that isn't as good of a check as toBe() because I don't want any room for error in what is returned.

I have already tried a workaround using toEqual();. However, while it works per se, I want toBe to pass as well because I want no room for error.

getAssignedChildren = () => {
    const { parent, allChildren } = this.state;
    const { children: assignedChildren } = parent || {};
    const assignedChildNames = [];

    if (!assignedChildren) {
        return [];
    }

    assignedChildren.forEach((assignedChildId) => {

        const childData = allChildren.find(
            (child) => child.childId === assignedChildId,
        );
        assignedChildNames.push(childData.childName);
    });

    return assignedChildNames;
};    





it("should get the assigned children for a given parent, push the 
names of said children into an array, and display the names of the 
children on the corresponding parent\b's detail page", () => {
    const { children } = parent;
    const { records } = allChildren;
    const props = {
        someStore,
    };

// allChildren is an imported mock data object
    const wrapper = createWrapper(ParentDetails, props, true);
    wrapper.setState({
        parent: { children },
        allChildren: records,
    });
    wrapper.getAssignedChildren();

    // TODO: Refactor toEqual to toBe in order to apply stricter 
equality checking
// for reference, the mock data object causes there to be a matched 
child-to-parent array to have a length of 5
// I need this toEqual to be a toBe
    expect(wrapper.getAssignedChildren()).toEqual([
        records[0].childName,
        records[1].childName,
        records[2].childName,
        records[3].childName,
        records[4].childName,
    ]);

    expect(children.length).toEqual(wrapper.getAssignedChildren().length);

The test passes with toEqual. However, toBe says:

expected ['child1', 'child2', 'child3', 'child4', 'child5'] but got ['child1', 'child2', 'child3', 'child4', 'child5']. The console error message reads: Compared values have no visual difference. Note that you are testing for equality with the stricter toBe matcher using Object.is. For deep equality only, use toEqual instead.

2
As it says toBe is using Object.is, which would return true only if the arrays are referentially equal. toEqual is what is to be used hereAgney
toBe is basically the same ===. Once you are creating a new array inside your method (btw, you should use map instead of forEach), toBe cannot pass.Sulthan

2 Answers

1
votes

Jest documentation states below:

toBe uses Object.is to test exact equality. If you want to check the value of an object, use toEqual instead.

Object.is gives whether 2 values are same value. In case of array, whether they have same reference or not. That's why you need to use toEqual to recursively checks every field of an object or array..

Documentation Link: https://jestjs.io/docs/en/using-matchers

Object.is: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is

0
votes

Object.is checks for equality. See below code. it won't compare values of array. I hope this clarifies your doubts about toBe and Object.is

//it will be false as it will check for referential equality
console.log(Object.is([1,2,3], [1,2,3]))
var arr = [1,2,3];
//it will be true
console.log(Object.is(arr,arr))
//but below will be false
console.log(Object.is(arr,[1,2,3]))
//same goes for objects
var obj = {value:1};
//it will be true
console.log(Object.is(obj, obj));
//but below will be false
console.log(Object.is(obj, {value:1}));

: