我应该如何测试两个嵌套的不可变js数据结构以实现深度相等?

时间:2017-07-01 17:35:04

标签: javascript testing immutability immutable.js jest

假设我有以下嵌套的不可变数据结构:

import { Record, List } from 'immutable'

const foo = List([
        Record({
           id: 1,
           gameState: Record({})
         })
       ])

我如何测试两个嵌套的不可变js数据结构是否彼此相等?

test.js

import jest from 'jest'
import { Record, List } from 'immutable'

describe('test', () => {
    it('that foo equals expected', () => {
        const expected = List([
              Record({
                 id: 1,
                 gameState: Record({})
               })
             ])
        expect(foo).toEqual(expected)
    })

2 个答案:

答案 0 :(得分:2)

ImmutableJS集合支持hashCode,它应该为不同的数据结构提供唯一的标识符,并为具有相同内容的数据结构提供相同的标识符。它在我看到的样本中递归地工作。

答案 1 :(得分:2)

对于大多数ImmutableJS类型,你得到的测试都可以正常工作。问题是你使用记录的方式。与Map,List等不同,构造函数Record(...)不返回新对象,它返回一个构造函数,然后可以用它来创建新对象。来自文档(https://facebook.github.io/immutable-js/docs/#/Record):

  

[Record]创建一个生成Record实例的新类。记录类似于JS对象,但强制执行一组特定的允许字符串键,并具有默认值。

如果您想要用户录制,那么您可以像这样编写测试:

import { Record, List, is } from 'immutable'

describe('test', () => {
    it('that foo equals expected', () => {
        const gameState = Record({});
        const gameRecord = Record({
            id: 1,
            gameState: new gameState()
        });

        const foo = List([
            new gameRecord()
        ]);

        const expected = List([
            new gameRecord()
        ]);
        expect(foo.equals(expected)).toBe(true);
    })
});

将此与使用Map而不是Record进行比较。下面使用jest的toEqual函数的测试按预期传递:

import { Map, List, is } from 'immutable'

describe('test', () => {
    it('that foo equals expected', () => {

        const foo = List([
            Map({
                id: 1,
                gameState: Map({})
            })
        ]);

        const expected = List([
            Map({
                id: 1,
                gameState: Map({})
            })
        ])
        expect(foo).toEqual(expected);
    })
});