9

プレイヤーが抽象クラスにアクセスし、それを拡張してロボットの動作を制御するプログラミング ゲームを開発しています。これはプログラミング ゲームであるため、ゲーム インフラストラクチャを保護して、プレイヤーがクラスだけでなくゲームを台無しにしないようにしています。このため、ほとんどのクラスを作成していfinalますが、ユニットテスト (mockito + testNG) でそれらをモックすることはできません。

だから私は疑問に思っていました、どうすればこれを回避できますか?クラスをテスト用に非最終のままにしてfinal、ビルドサイクルの後の段階で自動的に「-ize」する方法はありますか(回答に関連する場合に備えてmavenを使用しています)。別の外部ライブラリを追加したり、モッキング ライブラリを変更したりしたくありません。
それが不可能な場合は、2 つ目の質問があります。クラスfinalを本当に安全にしているのか? バイトコードから分類子を削除できるいくつかのライブラリを見たので、既にコンパイルされたクラスから削除できる場合はfinalおそらく役に立たないと思いますfinal

4

5 に答える 5

10

まず、物事を「最終」と宣言しても、人々があなたのゲームを台無しにするのを防ぐことはできません。リフレクションのトリックとコード生成ライブラリ全体があり、これを乗り越えるのが少し不便です。

したがって、決勝に負けた後は、jmock や任意のライブラリを使用してモックを作成できます。

于 2012-10-30T13:06:25.773 に答える
2

継承の代わりに委任をいつでも使用できます。

public interface Foo {
    // ...
}

public final class FooImpl implements Foo {
    // ...
}

public class MockFooImpl implements Foo {
    private FooImpl delegate;
    // ...
}

ただし、API に抽象クラスを含めることはお勧めできません。インターフェイスが良くなります。

于 2012-10-30T13:21:17.363 に答える
2

最終的には、 Jackpot 3RefactoringNGなどの自動リファクタリング ツールの適用を試みることができます。私はそれらをテストしたことはありませんが、リファクタリングの方法をとれば、あなたが望むことをする以上の能力があります.

もう 1 つの方法は、Powermock を使用して final と statics をモックすることです (デザインに何か問題があることを示唆しているため、statics をモックするのは好きではありません)。

于 2012-10-30T16:30:34.270 に答える
0

final通常、クラスはサブクラス化による拡張用に設計されていないため、ほとんどのクラスを作成することをお勧めします。私が知っている API 設計に関する本はすべて、そうすることを推奨しています (「Effective Java」、「Practical API Design」、「API Design for C++」)。これは、API 設計者の意図の表現、API の安全な進化、デッド コードの防止など、いくつかの理由で有益です (たとえば、優れた IDE は、finalメソッドがそのパラメーターのいずれかを使用していないことを検出します。または、句にリストされているチェック済み例外を決してスローしthrowsません。これは、非 final メソッドでは不可能です)。

上記のクラスのモックについては、 JMockitなどの適切なモック ツールを使用するだけで済みます(これは、特定の OO/API 設計プラクティスを犠牲にすることなく単体テストを記述したかったために開発したものです)。

于 2012-10-30T16:43:00.633 に答える
0

IMO、クラスは final とマークされ、オブジェクトを不変にします。クラスの動作を制御する場合は、クラス内のメソッドをプライベートとしてマークして、オーバーライドできないようにします。それらを保護したままにしておくと、誰かがクラスを拡張し、これらの保護されたメソッドをオーバーライドして、拡張されたクラスのインスタンスを、クラス オブジェクトをパラメーターとして期待する API に渡すことができるため、変更された動作が引き起こされます。したがって、公開したくないメソッドをプライベートとしてマークします。

これらのクラスを使用するクライアントによって、カスタム動作のためにオーバーライドできる保護/パブリック メソッドに関して拡張ポイントのみを残します。

于 2012-10-30T13:07:17.523 に答える