5

アプリの単体テストを作成していますが、プライベート メソッドをテストするクラスを見つけました。これは、特定のクラスの設計が不十分な結果である可能性がありますが、それを行う必要があります。おそらくQMetaObjectなどを使用して、Qtでプライベートメソッドを呼び出す方法はありますか?

単体テストには QTestLib フレームワークを使用しています。

4

5 に答える 5

5

適切な(読みにくい)答えは、プライベートメソッドをテストするべきではないということです。これらは実装の詳細;-)です。

OTOH-テスト中かどうかに応じて、条件付きで保護/プライベートを宣言してから拡張することを考えましたか?私は過去に同じようなピンチから抜け出すためにそれを使用しました。

#ifdef TESTING
// or maybe even public!
#define ACCESS protected
#else
#define ACCESS private
#endif

/* your class here */
class Foo {
ACCESS
    int fooeyness;
}

// or better yet, place this in a different file!
#ifdef TESTING
/*
    class which extends the tested class which has public accessors
*/
#endif
于 2011-09-12T21:31:34.677 に答える
2

解決策 1、迅速かつ簡単: テスト クラスをパブリック クラスのフレンドにします。

class Foo {
   // ...
private:
   friend class FooTest;
};

このようにして、FooTestクラスは public クラスのすべてのメンバーにアクセスできます。ただし、この方法では、別のテストからプライベート データにアクセスするたびに元のクラスを変更する必要があり、パブリック API でテストに関する情報が漏洩し、クラスの名前付けの競合が発生する可能性があります (/別の/ FooTest クラスの周り?) など。


解決策 2、別名適切に行われた: パブリック クラスにプライベート メソッドを配置しないで、パブリック メソッドでプライベート クラスを作成します。

class Foo {
    // 
private:
    friend class FooPrivate;
    FooPrivate *d;
};

FooPrivateインストールされていないか、include-privates/サブディレクトリなどにとどまっている可能性がある独自のヘッダーで宣言されます-つまり、通常の使用では邪魔になりません。public クラスはこのようにしてクリーンなままです。

class FooPrivate {
public:
    // only public stuff in here;
    // and especially this:
    static FooPrivate *get(Foo *f) { return f->d; }
};

テストには、プライベート ヘッダーとFooPrivate::get(fooObj)、プライベート クラス インスタンスを取得するための呼び出しが含まれており、それを問題なく使用しています。

于 2014-04-04T13:22:59.440 に答える
1

「プライベートメンバーは実装の詳細です」という考え方には同意しません。これは、大まかに「コードの一部のみをテストする」と解釈できます。

「ユニットはユニットである」という議論に関連することはできますが、ユニット内であっても、できるだけ多くのコードをテストでカバーしようとしないのはなぜですか? 別名。あなたのユニットに徹底的な直腸検査を与えます

そして、このイメージを念頭に置いて、他の回答では言及されていない、私が頻繁に使用しているアプローチの1つは、次のことです。

  1. protectedコード内ではなく、テストするメンバーを常に宣言privateします。
  2. テストコードでクラスをサブクラス化し、必要なセレクターを作成するか、そのサブクラスの実装のメンバーとしてテストコードを直接記述します。

注: 複雑なインスタンス化パターンに依存するクラスには注意して、それらを正しく構築する必要があります (参照: サブクラス ctor から元のクラスのコンストラクターを呼び出します)。

于 2016-07-17T13:18:33.837 に答える
1

これを行うためのより便利な方法を見つけました。まず、すべてのプライベート メソッドはプライベート スロットにする必要があります。次に、クラスのインスタンスを作成します。

Foo a;

次に、QMetaObject::invokeMethod を使用して、メソッドが持つ任意のスロット (パブリックまたはプライベート) を呼び出すことができます。したがって、メソッド Test を呼び出したい場合は、次のように実行できます。

QMetaObject::invokeMethod(&a, "Test", Qt::DirectConnection);

また、戻り値を取得して引数を送信することもできます...実際には、すべてここで回答されています: http://doc.qt.nokia.com/stable/qmetaobject.html#invokeMethod

于 2011-09-13T11:57:30.773 に答える
0

Unit Test は、保護された/プライベートなものではなく、クラスのパブリック インターフェイスをテストする必要があることを読んだことがあります。

あなたのクラスは、外側から正しく振る舞うべきです。実装戦略が変わっても、単体テスト クラスは変わりません。

于 2014-04-04T13:11:03.793 に答える