I am new to databases in general, so sorry if this question is too basic.

I'm trying to test a Playlist model which has a relationship with a Track model.

class Track(db.Model):
    """
    Model for storing track information
    """
    id = db.Column(db.Integer, primary_key=True)
    artist = db.Column(db.String(140))
    title = db.Column(db.String(140))
    created = db.Column(db.DateTime, default=func.now())
    track_id = db.Column(db.String(140))
    tempo = db.Column(db.Float)      
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))

    def __init__(self, title, artist, uri):
        self.title = title
        self.artist = artist
        self.uri = uri

    @property
    def serialize(self):
       """Return object data in easily serializeable format"""
       return {
           'id' : self.id,
           'title': self.title,
           'artist': self.artist,
           'track_id': self.track_id,
            'tempo':self.tempo
       } 

and then I have this secondary table:

tracks = db.Table('tracks',
    db.Column('track_id', db.Integer, db.ForeignKey('track.id')),
    db.Column('playlist_id', db.Integer, db.ForeignKey('playlist.id')))

here, the Playlist Model:

class Playlist(db.Model):
    """
    Model for storing playlist information belonging to a specific user
    """
    __tablename__ = 'playlist'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(50))
    created = db.Column(db.DateTime, default=func.now())    
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))

    tracks = db.relationship('Track', 
                            secondary=tracks,
                            backref=db.backref('playlists', 
                            lazy='dynamic'))

    def __init__(self, title):
        self.title = title

    @property
    def serialize(self):
       """Return object data in easily serializeable format"""
       return {
           'id' : self.id,
           'created' : self.created,
           'title': self.title,
           'tracks': [ item.serialize for item in self.tracks]
       }

and now I'm trying to test Playlist, like so:

test_playlist_model.py

import unittest
# third party libs
from sqlalchemy.exc import IntegrityError
# application modules
from project.api.models.base import db
from project.api.models.all import Playlist, tracks
from project.tests.base import BaseTestCase
from project.tests.utils import add_playlist


class TestPlaylistModel(BaseTestCase):

    def test_add_track(self):

        track = add_track(title='Karma Police',
                          artist='Radiohead',
                          uri='spofity:test')

        self.assertEqual(track.title, 'Karma Police')
        self.assertEqual(track.artist, 'Radiohead')
        self.assertEqual(track.uri, 'spofity:test')


    def test_add_playlist(self):

        track = add_track(title='Karma Police',
                          artist='Radiohead',
                          uri='spofity:test')

        playlist = add_playlist(title='Alternative')
        self.assertEqual(playlist.title, 'Alternative')
        self.assertTrue(playlist.id)
        self.assertEqual(playlist.tracks, track.serialize())

if __name__ == '__main__':
    unittest.main()

utils.py

from project.api.models.base import db
from project.api.models.all import Playlist

def add_playlist(title):
    playlist = Playlist(
        title=title)
    db.session.add(playlist)
    db.session.commit()
    return playlist

def add_track(title, artist, uri):
    track = Track(
                title=title,
                artist=artist,
                uri=uri
            )
    db.session.add(track)
    db.session.commit()
    return track

but I'm getting:

======================================================================
ERROR: test_add_playlist (test_playlist_model.TestPlaylistModel)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/src/app/project/tests/test_playlist_model.py", line 34, in test_add_playlist
    self.assertEqual(playlist.tracks, track.serialize())
TypeError: 'dict' object is not callable

what am I missing?

1 Answers

1
sleblanc On Best Solutions

Your method Track.serialize is actually a property, meaning that it returns a dictionary when you access it as if it were an attribute.

You should either drop the parentheses after track.serialize (and consider renaming the property to track.serialized to avoid confusion) or remove the @property decorator.


class Playlist(db.Model):
    ...

    def serialize(self):
        ...


class Track(db.Model):
    ...

    def serialize(self):
        ...