Skip to content

Instantly share code, notes, and snippets.

@Nicarim
Created November 6, 2019 15:20
Show Gist options
  • Select an option

  • Save Nicarim/75631616814d02ddfe1d1a517b8b7e13 to your computer and use it in GitHub Desktop.

Select an option

Save Nicarim/75631616814d02ddfe1d1a517b8b7e13 to your computer and use it in GitHub Desktop.
Theoretical quesiton that struck my mind related to ORM

A theoretical question about testing application state, which got stuck in my mind for a while:

Let's assume you're doing some kind of feature inside the code base, which requires you to create a new query to a Django Model. For example let's use Question model which we have. Requirement for my feature is that I want to retrieve Question with its some_field equal to 1337 or 1338 and I want it to present to a user.

class Question:
  id = PKField()
  one_of_bools = BoolField()
  some_field = IntegerField()
  date = TimestampField()

One most obvious way is that I do a query to database which will be something along these lines:

Question.objects.filter(some_field__in=[1337,1338]).all()

Which let's me have these Questions that match criteria be pulled from a database. I'd like to put that query into a function that can be used in my API view, so I wrap it in a function:

def get_specific_questions():
    return Question.objects.filter(some_field__in=[1337,1338]).all()

So I'll be retrieving them in single place, and reuse that part of the code whenever I need it (might be few different places, for the sake of argument).

Now to the actual quesiton that I have:

How do you test that function?

One obvious way is to just a test for best-case scenario:

def test_get_specific_questions():
    QuestionFactory(some_field=1337) # creates question in database
    QuestionFactory(some_field=1338) 

    questions = get_specific_questions()
    assert len(questions) == 2
    for question in questions:
        assert (question.some_field == 1337 or question.some_field == 1338)

But what do you actually test here?

We assume database of a perfect state where there are only two objects that match our criteria.

If I modify my query to be instead some_field__in=[1337, 1338, 1339], this test will still pass.

If I modify my query to be instead some_field__in=[1337, 1338], another_field=True this test will also pass.

I might also change it to be a query that retrieves all the objects (without filter) which I have in database - which will still work.

How do you test it in a way that the output is the only expected one - and any modification that doesn't match the requirements fail?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment