【PHPUnit】RefreshDatabaseについて
LaravelのPHPUnit で「おまじない」として毎回入れているuse RefreshDatabase
、
これはどのような動きをするか理解するため調べました。
RefleshDatabaseについて
テストケースの先頭にこんな感じで`use RefreshDatabase;'を記載している方は多いと思います。
この機能ですが、 テスト実行毎にデータベースを初期化するというものです。
例
RefreshDatabaseを使わない場合
カテゴリーというモデルがあったとして,それをテストメソッド内で5個のインスタンスを作る動きをします。
<?php class sample_Test extends TestCase { /** * サンプルテスト */ public function test_Sample(): void { Category::factory(5)->create()->each( function ($cat){ printf("ID: {$cat->id}\n"); } ); $this->assertTrue(true); } }
1回目の実行結果
ID: 1 ID: 2 ID: 3 ID: 4 ID: 5
2回目の実行結果
ID: 6 ID: 7 ID: 8 ID: 9 ID: 10
説明
2回目の実行結果は前回5個作っているので、6から再度作られます。 つまり、テスト実行毎に処理内容が変わってしまうわけです。
RefreshDatabaseを使う場合
use RefreshDatabase
をテストケースクラス先頭に追加しました。
<?php class sample_Test extends TestCase { use RefreshDatabase; //追加! /** * サンプルテスト */ public function test_Sample(): void { Category::factory(5)->create()->each( function ($cat){ printf("ID: {$cat->id}\n"); } ); $this->assertTrue(true); } }
1回目の実行結果
ID: 1 ID: 2 ID: 3 ID: 4 ID: 5
2回目の実行結果
ID: 1 ID: 2 ID: 3 ID: 4 ID: 5
説明
2回目の実行結果は前回5個作っているので、6から再度作られます。 つまり、テスト実行毎に処理内容が変わってしまうわけです。
まとめ
テストケースは毎回不変であるべき(じゃないとテストの意味がない)ので、
DBを使用するテストならuse RefreshDatabase
を使用して毎回DBを空にしてテストを行うことが最低条件になります。
こういう「毎回入れるもの」は入門本ではよくおまじないと言われますが、 実際に業務に使うなら、しっかりどういった動きをするものか把握してから使うべきと考えています。
【Django】日本語を含むJsonを返す方法2つ
DjangoのRest APIでJsonを返そうと思ったら思いの外ハマったポイントがあるのでまとめます。
何にハマった?
DjangoのAPIで商品モデル(Product)のデータを取得し、フロントのJavascriptで描画する、というものを作成していました。 そこで、jsonデータ自体は返せるもの、商品モデルのnameに日本語を使った文字列が入っているので、文字化けが発生。
Jsonの文字化けを防ぐため、色々と調べるとjson.dumps
でJSON文字列を作るときにensure_ascii
パラメータをFalse
に設定すると良い、という情報が
たくさん見つかりました。
これを参考に、以下のようなコードを組みましたが、今度はフロントエンド側でjson文字列がJSON.parce()
で正常に配列化されない。
gist.github.com
ここでハマりました。
原因
一度Json.dumps
でJson文字列を作っているのに、JsonResponse
でJson文字を再度Json化しようとしていたせいでした。
JsonResponseの実装を見ると
data=json.dumps(...)
でjson化しています。
ということは、JsonResponseを使うときはJson.dumpsしていない生のlistやdictを渡す必要があります。
公式DocにもdataはDictインスタンスを渡してね、って書いてありました。(・_・;) 悩んだら公式Docを読もう… docs.djangoproject.com
で、文字化けはどうするの?
JsonResponse
を使う場合、JsonResposneの引数json_dumps_params
にdump時のパラメータを渡せるので、
{"ensure_ascii"=False}
をパラメータと渡せば意図した結果になります。
JSONデータを返す2つの実装方法
というわけで、JSONデータを返すための実装方法はjson.dumps
を使ってHttpResponse
で返すか、JsonResponse
を使うか、になります。
JsonResponse版
こっちがスマート。 gist.github.com
HttpResponse版
Content-Typeをつけ忘れそうな気もする gist.github.com
近況
最近、Djangoでとあるサービスを開発したのですがより使いやすく・自然な操作感のUXデザインを実現するべく、
フロントエンドフレームワークのVue.js
を勉強しています。
フロントエンドフレームワークは初めて触るのでかなり手こずっていますが、勉強が一段落したら感想とか書いていきたいですね。
Djangoで連動するセレクタを作る
Djangoで連動するセレクタを作ってみました。 下記の3点を組み合わせます。
- セレクタの変更をトリガーとするイベントをjavascriptで作成
- javascriptの実行のため、セレクタの子要素
option
に属性を追加
DockerでDjango+MariaDB開発環境を構築
最近、MacをやめてWindowsマシンで開発をするようになりました。
8年ぐらい前はWeb開発といえば、Mac(Bashがあるから)という印象でしたが、 今はDockerでコンテナを作ってVSCodeでAttach, Linux上でコードをサクサク書いていけるので便利になりました!
ただ、今までDocker-Composeを触っていなかったので、
Pythonイメージからコンテナを作って、exec
コマンドでコンテナに入ってpip install django
等で環境構築していたので、
Docker-Composeを使ってより楽に構築してしまおう!とComposeを触ってみることにしました。
ブログ再開のお知らせ
久しぶりに技術ブログを再開します。
前回の記事がもう5年前ですが…
5年前から、色々忙しくしていました。
- 熊本移住
- 某外資系企業のBPOセンターでTechLeadをやっていました。
- VBA、BluePrimeなどで業務改善ソリューションをガンガン作る傍ら、チームビルディングなどなどあれこれに携わってました。
- 2021年7月に退職し、フリーランスとしての営業を始めることにし、今はその準備をしております。
このブログのこれから
今後、メインの言語はPython, Node.jsとして、Django, FlaskなどのWebフレームワーク、 Docker,LINE(Chatbot)などを扱っていきます。
Rubyは俺の中で死んだのだ。
読者がいれば、またよろしくお願いします。