5

統合テストで ShrinkWrap を使用して Jetty サーバーを起動しています。

問題:

テスト用の jetty-server を起動して、コントローラーのモックアップを作成すると、モックアップが機能しません! JMockit - AppClassLoader、Jetty - WebAppClassLoader.

質問:

モッキングをうまく機能させるには?

PS 私は、 -javaagent:jmockit.jarオプションが役立つかもしれないとグーグルで調べました。しかし、そうではありません。1.7 JDK ベースの Maven プロジェクトに必要ですか?

添加:

私の問題を説明するためにデモを書きました。参照で見つけることができます。

私のデモについて:

10 ストロークのコードを除けば、それらのプロジェクトと同じです。問題を説明するために、JMockit と 1 つのモックのみを追加しました。

JettyDeploymentIntegrationUnitTestCase.requestWebappメソッドが表示されるはずです。これらのメソッドでは、機能しないモックを作成します。

Jetty と JMockit が兄弟のクラスローダーによってクラスをロードすることを確認できるため、JMockit は単に Jetty のクラスを認識しません。

URLClassLoader
|
|-Launcher$AppClassLoader
|-WebAppClassLoader
4

1 に答える 1

3

ForwardingServletサンプル プロジェクトの JUnit テストは、クラスをモックしようとしています。しかし、組み込みの Jetty Web サーバーを使用するこのシナリオでは、実際にはこのクラスの2 つのインスタンスがあり、両方とも同じ JVM にロードされますが、異なるクラスローダーを介してロードされます。

クラスの最初のインスタンスは通常のクラスローダによってロードされ、JUnit テスト ランナーを開始するスレッドからクラスがロードされます ( AppClassLoader)。したがって、ForwardingServletテスト コードに表示される場合は、このクラスローダで定義されているものです。これは、モックするために JMockit に与えられたクラスであり、まさにそのとおりです。

しかしその後、Jettyの. このクラスは、JMockit には表示されません。ForwardingServletWebAppClassLoader

この問題には、次の 2 つの解決策があります。

  1. 何らかの方法でクラス オブジェクトを取得し、コンストラクターWebAppClassLoaderを呼び出してモックします。MockUp(Class)

  2. Web アプリのクラスにカスタム クラスローダーを使用しないように、Jetty サーバーを構成します。

2 番目の解決策は最も簡単で、ハンドラーを Jettyオブジェクトに設定する前にContextHandler、オブジェクトから作成されたオブジェクトに次の呼び出しを追加するだけで実行できます。WebArchiveServer

handler.setClassLoader(ClassLoader.getSystemClassLoader());

これをテストしたところ、期待どおりに機能し@Mock doGet(...)、実際のメソッドの代わりにメソッドが実行されましたForwardingServlet

于 2013-09-24T16:11:33.543 に答える