1

Having following function in views.py:

def ask_question():
        form = QuestionForm()
        if form.validate_on_submit():
            question = Question(title=form.title.data, text=form.text.data)
            db.session.add(question)
            db.session.commit()
            return redirect('/questions/%d/' % question.id)
        return render_template('ask_question.html', form=form)

How can I get an id of created model to put it in assertion?

def test_can_post_question(self):
    response = self.tester.get('/new-question')
    self.assert_200(response)
    form = self.get_context_variable('form')
    self.assertIsInstance(form, QuestionForm)
    response = self.tester.post('/new-question', data={'title': 'What about somestuff in Flask?',
                                                       'text': 'What is it?'})
    self.assertRedirects(response, '/questions/%d' % created_question.id)
                                                     #^ how can I get id of created model here?

I'm using Flask, Flask-SQLAlchemy, Flask-Testing

falsetru
  • 357,413
  • 63
  • 732
  • 636
micgeronimo
  • 2,069
  • 5
  • 23
  • 44

1 Answers1

1

Query the created question object. As a side effect, you can test that the question was created.

...
q = Question.query.filter_by(title='What about somestuff in Flask?').first()
self.assertRedirects(response, '/questions/%d/' % q.id)
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • That's what came first to my mind, but if there is mor elegant way? I've found somethind like `lastcreatedrow` method in SQLAlchemy docs but can not figure out how to use it – micgeronimo Jan 17 '15 at 09:32
  • 1
    @micgeronimo, You may use it to test the view. But what if you create another object after question? It will make your test fragile. – falsetru Jan 17 '15 at 09:34
  • sounds reasonable. Btw, is it correct `response = self.tester.post('/new-question', data={'title': 'What about somestuff in Flask?', 'text': 'What is it?'})` ? I'm getting None, when try to do this `q = Question.query.filter_by(title='What about somestuff in Flask?').first()` – micgeronimo Jan 17 '15 at 09:38
  • 1
    What do you get for response status code? 302 ? `self.assertEqual(response.status_code, 302)` – falsetru Jan 17 '15 at 09:40
  • Nope, I get status code 200. When I check my function manually in browser, everything works like should – micgeronimo Jan 17 '15 at 09:43
  • 1
    @micgeronimo, Then, ... it means `form.validate_on_submit()` returns `False`. Check the form. – falsetru Jan 17 '15 at 09:43
  • 1
    @micgeronimo, Could you try `self.tester.post` with `follow_redirects=False` argument? – falsetru Jan 17 '15 at 09:46
  • I've added this `app.config['WTF_CSRF_ENABLED'] = False` to `setUp` method of my test class. Everything now works, form validates. Thank you very much for assistance. – micgeronimo Jan 17 '15 at 09:48