(Solved)How to test the getMoviesByCountry correctly?

Probably a newbie question, I have succesfully created the function getMoviesByCountry, but when I create a test for the function, it fails? the function returns a empty array as it does not seem to be able to fetch from the database when I call it via a test.

 import MoviesDAO from '../../src/dao/moviesDAO';


test("Can perform a search by country Australia", async () => {
  const countries = [ "Australia" ];
  let result = await MoviesDAO.getMoviesByCountry(countries);
  expect(result).not.toBe([]);
  
  console.log(`result`, result); // this is always []

  const {title} = result;
  expect(title).toBe("The Story of the Kelly Gang"); // Fails
})

Please show your getMoviesByCountry implementation. I guess its related to it.

No problem :smiley:

  static async getMoviesByCountry(countries) {
  
    console.log(`countries: `, countries);
    let cursor
    try {
      
      cursor = await movies.find({ countries : { $all: countries } }, { projection: { title: 1 }});
      // console.log(`movieDao result: `, cursor.toArray());
            
    } catch (e) {
      console.error(`Unable to issue find command, ${e}`)
      return []
    }

    return cursor.toArray()
  }

The question could be clearer on this, but what is actually expected here is documents matching ANY of the items in the list as opposed to ALL items as your code currently implements.

Of course the best way is to actually read the code in the tests ( as the questions do instruct you to do ) and at least see what arguments are being passed and the expected number of results. This will then give you some indicator as to whether you are using the correct query operators and expressions.

SIDE NOTE: Not really important to the answer, but the async and await keyword usage in the provided code template is actually incorrect.

.find() is not actually an async method in itself, and therefore does not require an await keyword.

The only actual async function call here is the toArray(), and you don’t need to await that since getMoviesByCountry() is the actual method returning the Promise that requires the await, and that is done within the test file itself.

So for example your

console.log(`movieDao result: `, cursor.toArray())

testing statement should actually have been

console.log(`movieDao result: `, await cursor.toArray())

Otherwise it’s just a Promise still and not the result. But don’t do that since you can only iterate the cursor result once. Test your queries using the mongo shell before you code instead.

Also READ the test code but DON’T change it under any circumstance.

Your query should be $in not $all. A hint was even provided in the function description

@neillunn

Sorry you’re definitely correct, I should have worded the question better on my end.

The ticket has been completed and my method is working correctly :D, the website allows me to search for movies by country and genre no problems.

I have attempted to create my own test, just so I could learn how jest works a little more & have run into a problem. When I import the class to the test file and run it, the return result is undefined. The error message from jest seems to suggest that the method is unable to connect to the database when I run it from jest like this?

The second test passes no problems, while the test for getMoviesByCountry() fails.

import MoviesDAO from '../../src/dao/moviesDAO';

describe("Week 1 Tickets", async () => {
  let movies
  beforeAll(async () => {
    movies = await global.mflixClient
      .db(process.env.MFLIX_NS)
      .collection("movies")
  })

  // it("test to see if we can find genres", async () => {

  //   let genres = [ "Action", "Drama" ]
  //   let result = await movies.find({ genres: { $in: genres } }, { projection: { title: 1, _id: 0 }});

  //   const title = await result.toArray();
  //   console.log(`testing week1: `, title);
  // })


  it("Can perform a search by country Australia", async () => {
    const countries = [ "Australia" ];
    let result = await MoviesDAO.getMoviesByCountry(countries);
          
    console.log(`result`, result); // this is always []

    const {title} = result;
    expect(title).toBe("The Story of the Kelly Gang"); // fails
  })

  it("can find movie by country example", async () => {
    const countries = [ "Australia" ];
    const result = await movies.find({ countries : { $all: countries } }, { projection: { title: 1 }});

    let { title } = await result.next(); 
    expect(title).toBe("The Story of the Kelly Gang"); // passes
  })
})

You may have to understand what the error was in your code. For that, I’d like to tell you (and for those who will face the same problem or have the same code) that the $all keyword is telling that the field must match ALL the specified argument(s). In this case, it require that the countries have to contains ALL the countries in the array.

Reminder : official documentation : $all operator

@Sense

Thanks Sense, I’ll fix it now but strangely the code works and the status page is passing.

Careful, you might no have the last version of mflix-js. In the last one you may have the test case of it("Can perform a country search for three countries", in which the countries array variable contains multiple values ;

const countriesList = ["Russia", "Japan", "Mexico"]

I guess you don’t have the latest version of mflix-js folder.

@Sense

Ahh i see now, that makes more sense, I thought it was weird that I was getting a pass, glad i asked the other question now :slight_smile:

it("can find movie by country example", async () => {
    const countries = [ "Australia" ];
    const result = await movies.find({ countries : { $in: countries } }, { projection: { title: 1 }});

    let { title } = await result.next();
    expect(title).toBe("The Story of the Kelly Gang"); // passes
  })

I still cannot seem to figure out why my other test is failing though, Guess i’ll have to investigate the documentation more.

So I found the answer, if anyone reads this and is wondering :slight_smile:

Hi @Sense,

you may have the test case of it("Can perform a country search for three countries" , in which the countries array variable contains multiple values ;

I have just re-downloaded the course zip file (via Chapter 0) for mflix and I am still seeing the same test for 3 countries. Are you saying that in your version of projection.test.js there is no test for Can perform a country search for three countries?

Thanks:-)

Hello @juliettet, quite the opposite. I have this test, but it seems @lowfi didn’t as he was talking about the "Can perform a search by country Australia" test. :face_with_raised_eyebrow:

1 Like

Oh! OK…I just wanted to make sure that I was reading into what you said correctly so as not to further confuse my already (at the moment) confused brain.

Thanks for the clarification. :smiley:

@juliettet I created this test in another file juliettet :sweat_smile: sorry my question seems to have created a lot of confusion.

The question title should have been how to test a function, that connects to a database using jest :smiley:

Don’t sweat it. It’s part of the process. I’d actually like to learn more about what you were/are doing to test a function via Jest. I’m not at all familiar with it (yet).

Thanks for taking the time to explain your approach to testing :slight_smile:

1 Like