unittestでFileFieldを持つDjangoモデルのインスタンスを作成する
ユニットテストでFileFieldを持つモデルのインスタンスを作成する場合どう書くべきか
こんなモデルがあるとして
class UploadFile(models.Model): file = models.FileField(upload_to='file')
思いつくまま書いてたらいくつかエラーを出したのでメモしておく
1のopenしたファイルをを渡すというのは完全な間違いだけど、2のエラー(SuspiciousOperation)は初めてみた
正しく動いたのは3のdjango.core.files.Fileのインスタンスを渡す、だけどテスト実行で実際にMEDIA_ROOT以下にファイルが作成されてしまう
これは削除しておきたいけど、他にもっといい方法がないだろうか
# coding=utf-8 from django.core.exceptions import SuspiciousOperation from django.core.files import File from django.test import TestCase from apps.models import UploadFile class UploadFileTest(TestCase): def test_ok(self): file_path = '/Users/yuhei/test.txt' # 1. openしたファイルをわたすのは間違い with self.assertRaises(AttributeError) as cm: self.instance = UploadFile.objects.create(file=open(file_path)) self.assertEquals(cm.exception.message, "'file' object has no attribute '_committed'") # 2. パスを指定するとインスタンスを作成できるが読み出そうとするとエラーになる with self.assertRaises(SuspiciousOperation) as cm: self.instance = UploadFile.objects.create(file=file_path) file_contents = self.instance.file.read() self.assertEquals(cm.exception.message, "Attempted access to '/Users/yuhei/test.txt' denied.") # 3. from django.core.files import Fileのインスタンスとして渡す self.instance = UploadFile.objects.create(file=File(open(file_path))) file_contents = self.instance.file.read() # エラーにはならないが実際にMEDIA_ROOT以下にファイルが作成されるので削除する self.instance.file.delete()