gist.github.com埋め込みテスト

gistのリニューアルで、埋め込んだコードが崩れだしたので確認。

続きを読む・・・

Rhino.Mocksをちょっとだけ幸せにするお助けクラス

これはTDD Advent Calendar jp: 2012参加記事です。

前日(7日目)は、高野将さんの「TDDにIDEを活用しよう (VS2012+CodeRush Xpress)」でした。

さて、私の方はというと…ATNDの方にコメントで

windows8から搭載された、名前を出すことがはばかれる例のヤツをNUnitでテストする時の注意点とか(仮)

なんて書きました。

最大の敵は、なんといってもasync / await機構が対応していなかったためテストが書きづらく、そのための支援クラスをいくつか書いたので、それをさらそうと思っていました。

思っていました….。

そんな折、

NUnit 2.6.2 リリース ~ async/await に対応! (www.tdd-net.jp)

とのことで、もはや書く意味なくなりました。

なくなりました….。

なので別ネタに切り替えます。 で、最近コツコツ調べてる、Rhino.Mocks用のお助けクラスを書いたので、それを披露しようかと思います。

前ふりから…

Rhino.Mocksのお作法では、

  1. MockRepository.GenerateMock()でMockインスタンスを生成する
  2. Mockインスタンスに対し、Expect()とReturns()などでもって入り口と出口を差し替える。
  3. 走らせる。
  4. 最後にVerifyAll()で、通過したか確認

という、AAA (Arrange - Act - Assert)スタイルが用いられます。

より下層のユニってテストレベルだと、これで困らないのですが、より上層の振る舞いテストの場合、

  • ネットワークから情報抜き出し
  • ローカルに保存

などのリソースアクセスが複数登場してきます。 より下層のロジックをMock化しようとすると、複数のMockを作成して、各々に対してVerifyAll()を呼ぶというチョーメンドクサイ記述が必要です。

うっかり書き忘れるようものなら、目も当てられません。 まとめてVerify出来ればいいのに….。

実は、静的メソッドMockRepository.GenerateMock()とは別に、

  1. MockRepositoryのインスタンスを生成する
  2. CreateMock〜()を呼んで、Mockインスタンスを生成する
  3. 以下同文

というように、1つのレポジトリから複数のMockを生成することが出来ます。 最後に、MockRepositoryのVerifyAll()を呼んでやれば、まとめて通過検証ができると。

やってみました….。

残念、最初のA、つまりArrangeを行ってくれません。 従って、Mockを通過しないので、各MockのVerifyAll()がことごとく失敗します。 理由は、個々のMockに対し、MockRepository.Replay()が呼ぶ必要があるからです。

SO・KO・DE

ヘルパクラス書いちゃいました。 4147464 A Helper class to support uniform management of generared mock / stub for Rhino.Mocks.

なんてことはない、ただの拡張クラスです。しかもMockRepositoryAAA.csまるパクリ。

MockRepositoryの静的メソッドと同じ名前の拡張メソッドには出来なかったため、〜Helperというメソッド名にしていますが、引数は基本おなじはずです。

  1. MockRepositoryのインスタンスを生成する
  2. GenerateMockHelper()を呼んで、Mockインスタンスを生成する
  3. 以下同文

最後に、MockRepository.VerifyAll()を呼べば、まとめて通過検証できます。

やっつけで作ったものですが、それとなく使えているので、個人的に重宝してます。

明日(9日目)は、せとあずさ♂さんです。

Delphiとか依存性注入とか

これはDelphi Advent Calendar 2012参加記事です。

他の言語でDIコンテナ(依存性注入の方)を使用していて、ふと気づいたDI(依存性逆転の方)ついて、つらつらと。


普段会社では、いまだにDelphi 7をWindows7のXP Mode上で使ってる身です(主に保守ですが)。なのでDelphi 7 の話です(以降のバージョンは未経験)。

何も考えず、フォームやコンポーネントをプロジェクトに加えていくと、プロジェクトファイルである.dprにてインスタンス化されます。

Form1やDataModule2はそれぞれのソースファイルで宣言されたグローバル変数で、コンポーネントのインスタンスが初期化されてます。

よく言われる一般論として、

  • スコープを小さくするかが重要
    • -> グローバル変数もってのほか
  • ムダなオブジェクトは作らない
    • -> 起動時にインスタンス化とか頭沸いてる

そのため私はよくこれらのグローバル変数の宣言を削除し、使う直前でインスタンス化するように変更したりしてます。 ところで、このグローバル変数に起動時に突っ込む挙動、見方を変えると面白い側面が見えてきます。

実際に使用する時点で、確実に初期化が完了しており、インスタンスが決定されている。 別の言い方で、依存が解決されているともいえる。

オブジェクトを生成する場合、1クラスだけで終わることは稀で、たいていは複数クラスが絡み合う。 それらはコンストラクタやメソッドの引数、プロパティでセットされるでしょう。 クラス継承が絡むと、組み合わせはさらに増大。

使う側(フォーム等)で

  • 自身でインスタンス化する場合
    • 具体的なクラス構成をすべて理解しておく必要あり
    • でないとインスタンスを作れないから
  • 初期化済み
    • 内側の具体的な内容が隠される(ように見える)

その結果、フォームやコンポーネント

  • 独立性が高まる(ように見える)
  • より再利用可能になる(ように見える)

使う人が、使う時点でなく他に任せて、依存を解決。 目を細めてみれば、依存が逆転しているように捉えている気がする今日この頃。

Advent Calendar 2012 Winter (C#)

これはC# Advent Calender 2012参加記事です。

今年の2月〜10月の間、Windows8の名前を発してはいけないアプリを開発していて、その間にいくつか小道具を作ってはgistに放り込んだので、使えるもの使えないものひっくるめて、大掃除がてら、いくつか紹介いたします。

gist: 2418469 A helper class to extract property-names of ViewModel for MVVM.

WPFでMVVM的なことをやってて、いつも気になるのが INotifyPropertyChanged.PropertyChanged イベントを介して通知を行う際の引数。

あの文字列で渡すってのが、もう気に入らないです(個人的感想です)。 カターンゼンじゃないし…(個人的感想です)。 C# 5.0からは、CallerInfoAttributeが追加されて、幾分楽にはなってるっぽいですが、read-onlyなプロパティにも値をセットしなきゃならんとかチョーメンドイわけです(個人的感想です)。

文字列は自由に表現が出来る分、記述間違いにかどうかは実行時でないと分からない問題を持っていますので、できるだけコンパイル時に蹴ってもらえるよう、専用の型を与えたいと思っていました。 そこで、上のようなコード書いてみました。

使い方は以下のように。。。

プロパティにPropertyCategoryAttribute(Type)を付与します。 コンストラクタで、PropertyCategoryMapperをインスタンス化します。 View Modelの各処理の通知個所で、ToProprtyNames<SomeType>()を呼ぶことで、すべての対象のプロパティ名が取得できます。 複数のPropertyCategory属性を付けておけば、タグごとに通知するプロパティを切り替えることが出来るようになります。

参考までに、このgistには、テストコードも付けてます。

本当はPropertyCategory属性の引数に列挙値(enum)を渡したかったのですが、Attributeの仕様で定数、Typeまたはそれらの配列しか認められていなかったため、代わりにinterfaceを使用しました。

それと1回だけとはいえ、リフレクションに頼ってしまったのも辛いところです。しかし、世界中の誰かがきっと、ろずりーんでコンパイル時に生成するコードを書いてくれると信じています。私は、にわかなのでムリです。

以下、疲れたので簡単に。。。

3521721 Any filter extension

何となく思いついた、Enumerable.WhereでOr (||) を指定するのと同じものです。 Orでもいいんだけど、どこで改行したらいいか分からなくなってイヤーンだし、個々の述語関数使い回したかったし、という理由で作っちゃいました。ホントただの俺得です。

つい最近気づきましたが、Enumerable.Whereって、要素とインデックスが渡されるオーバーロードがあったんですね。 なので作ってはないんですの。

もう一つ、俺得クラスとして、コレクションのfull outer join書いたけど、gistにあげ忘れてたから省略。てへへ。

3046512 Maybeモナドの写経

見ての通り、matarillo.com / モナドの驚異の写経です。 ただ、ちょっとだけ手を入れて、c# 5.0のasync / awaitにも対応させてみました。

モナドとかよく分からないですので、写経元見てもらった方がいいと思います。

以上、淡々と並べてみました。

立ててみた

世間様では、明日から「あどべんと かれんだー」なるものが同時多発的に行われるようですね。 前からやってみたいなと思ってましたが、いつも時間が取れず見る側でした。

今年は11月から、割とゆっくりとした進行だったので、参加ついでにgithub page作ってみました。 (11月頭に作って、放置プレー状態でしたががが)

今のところ、

の3つを予定してます。 まずはC# の記事をなんとか仕上げなければ(しろめ)

Test

テスト本文

  • りすと1
  • りすと2

Alt マウンテン獅子

Picture Step1