Search code examples
javascriptsqlpostgresqltestingpg

Failing TEST of INNER JOIN query using postgreSQL and Tape(npm module)


I have a SQL query which seems to be working fine when I use it directly in my PostgreSQL database, however I am struggling to make my Tape test for it pass as the expected output is not what I expect.

I have pasted my actual query in my pgcli/database interface and it works fine.

  1. In my findQueries.js file I have the following function:
const findAllFoodItems = cb => {
    dbConnection.query(
        'SELECT products.name, categories.name FROM products INNER JOIN categories ON products.category_id = categories.id;',
        (err, res) => {
            if (err) {
                cb(err);
            } else {
                cb(null, res.rows);
            }
        }
    )
}

module.exports = { findAllFoodItems }
  1. My test for the function:
test("Check findAllFoodItems queries correctly", t => {
    findAllFoodItems((err, res) => {
        if(err) {
            t.error(err, "Unable to findAllFoodItems");
            t.end();
        } else {
            const expected = [{"Banana": "Fruit"}, {"Potato": "Vegetables"}, {"Sausages": "Meat"}, {"Apple": "Fruit"}];
            t.deepEquals(res, expected);
            t.end();
        }
    })
});
  1. When I runs the query in my database I get my desired output:
SELECT products.name, categories.name 
FROM products 
INNER JOIN categories ON products.category_id = categories.id;

OUTPUT:

+----------+------------+
| name     | name       |
|----------+------------|
| Banana   | Fruit      |
| Potato   | Vegetables |
| Sausages | Meat       |
| Apple    | Fruit      |
+----------+------------+

Tape/test failing report:

operator: deepEqual
      expected: |-
        [ { Banana: 'Fruit' }, { Potato: 'Vegetables' }, { Sausages: 'Meat' }, { Apple: 'Fruit' } ]
      actual: |-
        [ { name: 'Fruit' }, { name: 'Vegetables' }, { name: 'Meat' }, { name: 'Fruit' } ]

Solution

  • The first problem is that both columns returned by your query have the same name (ie name). Postgres happily deals with that, however that may cause ambiguity on the client end, especially if it uses the column names as keys, which seems to be the case here. You would need to alias the columns in the result set, like:

    SELECT products.name pname, categories.name cname FROM ...
    

    The second problem is that your expected result is not correct. Your driver seems to return an array of key/value pairs, where the keys are the column names. Hence you should check for the following output:

    [ 
        { pname: 'Banana', cname: 'Fruit' }, 
        { pname: 'Potato', cname: 'Vegetables' }, 
        { pname: 'Sausages', cname: 'Meat' }, 
        { pname: 'Apple', cname: 'Fruit' } 
    ]