0

I have an user object - I want to generate test for each user property and check if it's the right type. However as typeof array is an object assertion fails on array properties with "AssertionError: expected [ 1 ] to be an object".

I have therefore checked if the property is an array and then generate special test for it. I'm wondering if this is the right approach? I have a feeling I'm misssing something obvious.

Object.keys(pureUser).forEach(property =>{
    // since typeof array is an object we need to check this case separately or test will fail with expecting array to be an object
    if (Array.isArray(pureUser[property])) {
         it(`should have property ${property}, type: array`, function () {
             user.should.have.property(property);
           });
         } else {
             it(`should have property ${property}, type: ${(typeof pureUser[property])}`, function () {
                 user.should.have.property(property);
                 user[property].should.be.a(typeof pureUser[property]);
             });
         }
    });

pureUser is something like this:

let pureUser = {
    username: "JohnDoe123",
    id: 1,
    categories: [1,2,3,4]
}

User variable is defined elsewhere via got.js

huaLin
  • 97
  • 2
  • 13
t-str-os
  • 57
  • 6
  • The user variable doesn't seem to be defined. – jro Apr 22 '19 at 09:11
  • Yes, I get the user variable on other place in the code. This code does generate the test and checks for types, but as I've said I think I'm doing it the wrong way. – t-str-os Apr 22 '19 at 09:15
  • Is it possible to post the data in the user variable in your question? – jro Apr 22 '19 at 09:16
  • user variable is exactly the same as pureUser so user = { username: "JohnDoe123", id: 1, categories: [1,2,3,4] }. The difference is that pureUser is hardcoded and user is gained from API and tested against expected result ( pureUser ). – t-str-os Apr 22 '19 at 09:27

1 Answers1

0

change your test to be pureUser[property].should.be.an.Array or user[property].should.be.an.Array

forEach

The forEach() method calls a provided function once for each element in an array, in order.

let pureUser = {
username: "JohnDoe123",
id: 1,
categories: [1,2,3,4]
}

Object.keys(pureUser).forEach(property =>{

        // since typeof array is an object we need to check this case separately or test will fail with expecting array to be an object
        if (Array.isArray(pureUser[property])) {
        
            console.log('Yes, it\'s an Array')
            //it(`should have property ${property}, type: array`, function () {
            //    user.should.have.property(property);
            //});
        } else {
            console.log('No, it\'s not an Array')
            //it(`should have property ${property}, type: ${(typeof property)}`, function () {
                //user.should.have.property(property);
               // user[property].should.be.a(typeof pureUser[property]);
            //});
        }

    });

When you use forEach on pureUser, the parameter will be the objects properties, like username, id, etc

let pureUser = {
username: "JohnDoe123",
id: 1,
categories: [1,2,3,4]
}

Object.keys(pureUser).forEach(property =>{
  console.log(property);
});

You can also access the array in your forEach function.

arr.forEach(item, index, arr)
Junius L
  • 15,881
  • 6
  • 52
  • 96
  • If I change this I always have typeof returning "string" and tests fail. – t-str-os Apr 22 '19 at 09:32
  • The property will never be an array, so the if statement will never evaluate to true – jro Apr 22 '19 at 09:33
  • Actually it will return true if the property is an array. – t-str-os Apr 22 '19 at 09:37
  • @Junius thank you for your time, but unfortunatelly this does not answer my question. My question is is there more elegant way to check for property types within the object than the one I have posted. – t-str-os Apr 22 '19 at 09:43
  • @t-str-os I think you should change your test to be `pureUser[property].should.be.an.Array` instead of `user.should.have.property(property);` – Junius L Apr 22 '19 at 09:50