-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CClipboard のテストにモックを導入する #1800
CClipboard のテストにモックを導入する #1800
Conversation
* CDocEditor.h に実装されていた CClipboard の呼び出しコードを CDocEditor.cpp に移動。 * CDocEditor.h から #include "_os/CClipboard.h" を除去。 * 不足していた #include を追加。
* モックしたい関数を呼び出しているコードから名前空間指定を除去。 * モックしたい関数と同名の仮想メンバ関数をクラスに追加し、元の API へリダイレクトするように実装。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
とりあえずコメントのみです。
@@ -56,7 +56,7 @@ CClipboard::~CClipboard() | |||
|
|||
void CClipboard::Empty() | |||
{ | |||
::EmptyClipboard(); | |||
EmptyClipboard(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ぬおっ!
やり方色々あるっす。
方法 | メリット | デメリット |
---|---|---|
APIを自クラスのメンバとして定義する | 書き換えが楽。 | 自クラスのメンバーがけっこう増える。 |
APIラッパークラスを定義してGetする | 自クラスのメンバー追加は1個で済む。 | ラッパークラスの定義内容でモメるかも。 |
APIラッパークラスを定義してシングルトンにするする | 自クラスのメンバーは増えない。 | ラッパークラスの定義内容でモメるかも。 |
たとえばこんな感じです。
CClipboardApi::getInstance()->EmptyClipboard();
|
||
// CF_HDROP を指定して取得する。 | ||
TEST_F(CClipboardGetText, DISABLED_HDropSuccess) { | ||
// 適切なダミーデータを用意するのが難しいため未実装 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここは一旦コレでよいと思いました。
✅ Build sakura 1.0.4044 completed (commit f0b5309a9f by @k-kagari) |
✅ Build sakura 1.0.4045 completed (commit 7f18f51acb by @k-kagari) |
雑に実装してみました。 気付いたこと
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GMockを使ってクリップボードの変更を抑止することはできていると思いました。
「あるべき」と思ったことの指摘を挙げましたが、対応は任意でよいです。
GMockを使うのと
GMockを正しく使うのは違うと思うので、
「意図通り機能しているならOK」で良いように思います。
@@ -673,3 +673,19 @@ int CClipboard::GetDataType() | |||
if(::IsClipboardFormatAvailable(CF_HDROP))return CF_HDROP; | |||
return -1; | |||
} | |||
|
|||
HANDLE CClipboard::SetClipboardData(UINT uFormat, HANDLE hMem) { | |||
return ::SetClipboardData(uFormat, hMem); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
このAPI関数ですが、クラスメンバを利用しないのでconst関数とすべきだと思います。
他のAPI関数も同様です。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const にしました。
|
||
protected: | ||
// 単体テスト用 | ||
explicit CClipboard(bool openStatus) : m_bOpenResult(openStatus) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここにexplicitを付けるなら、元々定義されているコンストラクタにも付けるべきと思いました。
コメントで書きましたが元のコンストラクタがおかしいので、ここに追加したコンストラクタは将来的に削除されることになると思っています。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
既存のコードの改善を始める前にテストを整備したいので元のコンストラクタには手を付けていません。
失敗の可能性があるコンストラクタは static なファクトリー関数に置き換えるのが良いと考えています。クリップボードのオープンに失敗したら即座に呼び出し元に通知するべきです。状態を持つ必要がなくなるのでクラス内の条件分岐が減らせます。
このあたりの設計については各論あると思いますのでまたの機会に詳しく検討させてください。
sakura_core/_os/CClipboard.h
Outdated
virtual HANDLE SetClipboardData(UINT uFormat, HANDLE hMem); | ||
virtual HANDLE GetClipboardData(UINT uFormat); | ||
virtual BOOL EmptyClipboard(); | ||
virtual BOOL IsClipboardFormatAvailable(UINT format); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
コンストラクタ・デストラクタとメソッドの間には、なんらかの区切りが欲しいです。
ここに追加したメソッドはAPIに転送するものなおんで、constを付けるべきです。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
追加するメンバ関数の前にコメントを追加しました。
tests/unittests/test-cclipboard.cpp
Outdated
MOCK_METHOD2(SetClipboardData, HANDLE (UINT, HANDLE)); | ||
MOCK_METHOD1(GetClipboardData, HANDLE (UINT)); | ||
MOCK_METHOD0(EmptyClipboard, BOOL ()); | ||
MOCK_METHOD1(IsClipboardFormatAvailable, BOOL (UINT)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
マクロMOCK_CONST_METHODnでconstメソッドを定義できるようです。
* 仮想メンバ関数を const にした。 * 仮想メンバ関数の宣言部に目的を説明するコメントを追加した。
Kudos, SonarCloud Quality Gate passed! |
✅ Build sakura 1.0.4047 completed (commit 24090e889b by @k-kagari) |
レビューありがとうございました。マージします。 |
|
すぐに次弾が出てくると予想してたので放置してました。 把握している問題点
|
Uninteresting mock function call は ON_CALL を呼び出したメソッドに対しても表示されるものです。表示しないようにしたければログレベルを下げるという方法があります。コマンドラインフラグで指定できるようです。
これは把握していませんでした。
この2点は追加パッチで対処するつもりでしたが、個人的に余裕がない時期が続いており準備が進んでいません。 |
すっかり忘れていましたが、自分の環境で「たまにコケる」原因は #1823 (comment) と考えられます。 |
PR の目的
CClipboard のテストにモックを導入し、プラットフォームのクリップボードへの依存を除去します。
カテゴリ
PR の背景
CClipboard の自動テストにモックを導入する検討を行っています。 #1798 により tests1.exe で Google Mock が使用できるようになりましたので、試験的に既存のテストをモック化したものを追加したいと思います。
プロジェクト内での実績がない類の変更であることもあり、当面は既存のテストと併存させる方向で検討中です。
仕様・動作説明
コミットを三分割しています。
PR の影響範囲
CClipboard の既存コードに変更を加えますが、動作を変更するものではありません。
参考資料