higan96技術メモ

https://github.com/higan96

定義済みクラスで「Use of undeclared type "ClassName"」のエラー

とっくに定義済みのクラスなのundeclaredと言われて怒られた。

Use of undeclared type "ClassName"

解決方法

右側の「Taget Membership」でテストターゲットの方にもチェックを入れる。

原因

あるクラスのテストを書こうとクラスが定義されたファイルだけテストターゲットに含めても、そのクラスの中で使われているクラスであれば、そのクラスが定義されたファイルもテストターゲットに含めないとエラーが出る。

これは、ビルド時にも起こる。

自分はそういったケースはテストの時にしか発生しないと思っていたので、ちょっとはまった。

ダミーのjsonファイルからjsonデータを作る

サーバーサイドの実装がまだだけど、APIの仕様が決まっているようなときに。 開発が進んだらjsonファイルは消すか、ターゲットをテストだけにしよう。

How do I create dummy JSON data on the client in objective C / iOS? - Stack Overflow

let filepath = NSBundle.mainBundle().pathForResource("dummy", ofType: "json")
var jsonDict:NSDictionary?
        
if let unwrappedFilepath = filepath{
    let jsonData = NSData(contentsOfFile: unwrappedFilepath)
    if let unwrappedJsonData = jsonData{
      var error:NSError?
      jsonDict = NSJSONSerialization.JSONObjectWithData(unwrappedJsonData, options: nil, error: &error) as? NSDictionary
    }
}

Rspecでインスタンス変数に任意の値がセットされているかテストする方法

タイトルのままです。
GETメソッドなんかで、インスタンス変数の値に期待通りの値がセットされているかをcontrollerのテストで行う方法です。

it { expect(controller.instance_variable_get("@user").name).to eq  'hoge' } 

ここではインスタンス変数@userのnameが'hoge'であるかのテストをしています。

updateでバリデーションの検証

どっかでとちりそうなのでメモ
update - リファレンス - Railsドキュメント

バリデーションによる検証を行う

  • update
  • update_attributes

バリデーションによる検証を行わない

  • update_all
  • update_attribute

Rspecでbefore_actionなどをテストするときはAnonymousControllerを使うと便利

ApplicationControllerなどにすべてのControllerで読み込まれるbefore_actionなどを定義していて、そのbefore_actionをテストをしたいときは、AnonymousControllerを使うと便利です。

anonymous controller - Controller specs - RSpec Rails - RSpec - Relish

ようは、テストだけにつかうコントローラとアクションをテストの度に作って、before_actionなんかの振る舞いをテストできるわけです。

describe ApplicationController do
  controller do
    def index
    end
  end
end

これで、おわり。Annonymousコントローラのindexアクションがこれでできあがり。
最初、ルート設定が必要なのかなと思っていたけど、特に必要ないっぽい。

使いどころとしては、ApplicationControllerなので通常アクションを持たせないけどbefore_actionはここに書いている、っていうよくあるパターン。before_actionのテストをどこで書くのさ、となったときに他の特定の機能を持たせているコントローラに書くと、なにかそのコントローラに特有のテストのようになってしまうし、テストの条件が偏る。

要は、ApplicationControllerに定義した機能はApplicationControllerでテストしたほうがわかりやすいので、AnonymousController超便利ってことです。

sessionに保存されたHashの挙動がストア前後で変わる。

sessionに保存されたHashの挙動がストア前後で変わる。

session[:test_data] = {hoge: ‘fizz’, fuga: ‘buzz’ }

としたとき、session[:test_data]の中身は

{:hoge =>’fizz’, :fuga => ‘buzz’}

となる。
しかしこれが別のアクションで使用するとき、つまり一度ストアされると、

{‘hoge’ =>’fizz’, ‘fuga’ => ‘buzz’}

このように、keyがシンボルから文字列に変わっている。

これ、stackoverflowにも質問がありました。
session - Ruby on Rails sneakily changing nested hash keys from symbols to strings - Stack Overflow
回答

Sessions, if you're using cookie ones, do not live in Ruby - they are transmitted back and forth across the network. The session object you stored your data in is not the same session object that you tried to read it from. And while in cookie form, there is no difference between strings and symbols. Use Hash#symbolize_keys! to be sure you have your keys as you wish, or just use the string keys consistently.

解決方法としては

  • シンボルではなく文字列を使う
  • symbolize_keys!を使用する

ということらしい。

cookieの仕様っぽいですね。

使っていないminitestでWarningが出たよ問題

version:
rails: 4.1


rails4.1にupdateしたら、使っていないはずのminitestを要求されて、困惑しました。

Warning: you should require 'minitest/autorun' instead.
Warning: or add 'gem "minitest"' before 'require "minitest/autorun"'

shoulda-matcherが原因でしたアップデートしましょう。

shoulda-matcher: 2.5

shoulda-matcher: 2.6