factory_boy 2.4.0 で仕様が変った

Python の Fixture ツールである factory_boy を最新版の 2.4.0 にアップデートしたら、今までテストが通っていたものが fail するようになった。

# -*- coding: utf-8 -*-
from factory import Sequence
from factory.alchemy import SQLAlchemyModelFactory
from models.db import session
from models.entities.user import User
        

class UserFactory(SQLAlchemyModelFactory):
    FACTORY_FOR = User
    FACTORY_SESSION = session
    FACTORY_HIDDEN_ARGS = ('id',)
        
    id = Sequence(lambda n: n)
    name = Sequence(lambda n: u'User%d' % n)
    password = Sequence(lambda n: u'password%d' % n)
    email = Sequence(lambda n: u'user%d@example.com' % n)

元々のコードがこれだったが、テストを実行すると以下のメッセージが表示された。

Cannot generate instances of abstract factory UserFactory; Ensure UseryFactory.Meta.model is set and UserFactory.Meta.abstract is either not set or False.

ドキュメントを探してみると、class Meta を使うようになったよう。
Reference — Factory Boy latest documentation

という訳でこういう感じになった。

from factory import Sequence
from factory.alchemy import SQLAlchemyModelFactory
from models.db import session
from models.entities.user import User


class UserFactory(SQLAlchemyModelFactory):
    class Meta:
        model = User
        sqlalchemy_session = session
        abstract = False
        inline_args = ('name', 'password', 'email',)
        exclude = ('id',)

    id = Sequence(lambda n: n)
    name = Sequence(lambda n: u'User%d' % n)
    password = Sequence(lambda n: u'password%d' % n)
    email = Sequence(lambda n: u'user%d@example.com' % n)

SQLAlchemy を使う場合には sqlalchemy_session に格納するように変った。
また SQLAlchemy の model で以下のように __init__() で登録している場合は、inline_args を使う必要がある。

def __init__(self, name, password, email):
    self.name = name
    self.password = password
    self.email = email

逆に id のように自動で生成するものは exclude に格納する。