Chai - Testing for values in array of objects

后端 未结 6 1276
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-01 12:22

I am setting up my tests for the results to a REST endpoint that returns me an array of Mongo database objects.

[{_id: 5, title: \'Blah\', owner: \'Ted\', de         


        
相关标签:
6条回答
  • 2021-01-01 12:40

    ES6+

    Clean, functional and without dependencies, simply use a map to filter the key you want to check

    something like:

    const data = [{_id: 5, title: 'Blah', owner: 'Ted', description: 'something'},{_id: 70, title: 'GGG', owner: 'Ted', description: 'something'}];
    
    
    expect(data.map(e=>({title:e.title}))).to.include({title:"Blah"});
    

    or even shorter if you only check one key:

    expect(data.map(e=>(e.title))).to.include("Blah");
    

    https://www.chaijs.com/api/bdd/

    0 讨论(0)
  • 2021-01-01 12:49

    Here is another approach that I found to be more helpful. Basically, use string interpolation and map your array of objects to an array of string literals. Then you can write expectations against the array of strings.

    const locations: GeoPoint[] = [
      {
        latitude: 10,
        longitude: 10
      },
      {
        latitude: 9,
        longitude: 9
      },
      {
        latitude: -10,
        longitude: -10
      },
      {
        latitude: -9,
        longitude: -9
      }
    ];
    const stringLocations: string[] = locations.map((val: GeoPoint) => `${val.latitude},${val.longitude}`);
    
    expect(stringLocations).to.contain('-9.5,-9.5');
    expect(stringLocations).to.contain('9.5,9.5');
    
    0 讨论(0)
  • 2021-01-01 12:53

    This is what I usually do within the test:

    var result = query_result;
    
    var members = [];
    result.forEach(function(e){
        members.push(e.title);
    });
    
    expect(members).to.have.members(['expected_title_1','expected_title_2']);
    

    If you know the order of the return array you could also do this:

    expect(result).to.have.deep.property('[0].title', 'expected_title_1');
    expect(result).to.have.deep.property('[1].title', 'expected_title_2');
    
    0 讨论(0)
  • 2021-01-01 12:55

    An alternative solution could be extending the array object with a function to test if an object exists inside the array with the desired property matching the expected value, like this

    /**
     * @return {boolean}
     */
    Array.prototype.HasObjectWithPropertyValue = function (key, value) {
        for (var i = 0; i < this.length; i++) {
            if (this[i][key] === value) return true;
        }
        return false;
    };
    

    (i put this in my main test.js file, so that all other nested tests can use the function)

    Then you can use it in your tests like this

    var result = query_result;
    // in my case (using superagent request) here goes
    // var result = res.body;
    
    result.HasObjectWithPropertyValue('property', someValue).should.equal(true);
    
    0 讨论(0)
  • 2021-01-01 12:57

    Probably the best way now a days would be to use deep.members property

    This checks for unordered complete equality. (for incomplete equality change members for includes)

    i.e.

    expect([ {a:1} ]).to.have.deep.members([ {a:1} ]); // passes
    expect([ {a:1} ]).to.have.members([ {a:1} ]); // fails
    

    Here is a great article on testing arrays and objects https://medium.com/building-ibotta/testing-arrays-and-objects-with-chai-js-4b372310fe6d

    DISCLAIMER: this is to not only test the title property, but rather a whole array of objects

    0 讨论(0)
  • 2021-01-01 13:02

    As stated here following code works now with chai-like@0.2.14 and chai-things. I just love the natural readability of this approach.

    var chai = require('chai'),
        expect = chai.expect;
    
    chai.use(require('chai-like'));
    chai.use(require('chai-things')); // Don't swap these two
    
    expect(data).to.be.an('array').that.contains.something.like({title: 'Blah'});
    
    0 讨论(0)
提交回复
热议问题