Android アクティビティをテストするときは、本番環境で実行するときとは異なる実装クラスをインターフェイスに使用する必要があります。私はモック オブジェクトの使用に慣れていますが、問題は、Android のアクティビティが私ではなく OS によってインスタンス化されることです。したがって、アクティビティへの参照を取得するまでに、それは既にインスタンス化されており、既に実装クラス。私の場合、話しているクラスは Login クラスです。私の自動テストでは、ログイン結果を制御できるようにしたいと考えています。これが私の例です:
class MainActivity extends Activity {
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
setContentView(R.layout.main);
LoginMgr aLoginMgr = new LoginMgrImpl();
if (aLoginMgr.authenticated()) {
//do something
} else {
//do something else
}
}
}
public interface LoginMgr {
public boolean authenticated();
}
ライブラリの他の場所には、実装クラスがあります。
public class LoginMgrImpl implements LoginMgr {
//authenticate
}
LoginMgrImpl
自動テスト中に、本番環境を、テストに必要なブール値を返すテスト バージョンに置き換えられるようにしたいと考えています。MainActivity
で別の を使用する方法がわからないため、ここで助けが必要LoginMgrImpl
です。それが重要な場合、私はEclipseを使用しています。getActivity () を呼び出すとActivityInstrumentationTestCase2<MainActivity>
、テスト クラスによって が作成されます。MainActivity
引数なしのコンストラクターを呼び出すため、そこで変更する機会はありませんLoginMgrImpl
。MainActivity
Eclipse がビルドを制御するため、別の実装ライブラリで ビルドする方法がわかりません。
経験豊富な方で、私のテストをうまく自動化するための方向性を教えてもらえますか? Activity オブジェクトで使用されるいくつかのテスト クラスをモックしようとしているのは私だけではありませんが、フォーラムで解決策を見つけるのに何時間も費やしましたが、成功しませんでした。ヘルプ!
皆さんからのフィードバックに基づいて、さまざまな解決策を試しましたが、問題なく使用できる 2 つの解決策を見つけました。
解決策1:1つはマークされた回答で説明されており、元のsrc、res、assetsフォルダーとAndroidManifest.xml
. その後、プロジェクトのリンクされたバージョンのプロジェクト プロパティを変更して、テストをサポートする別のライブラリ実装を参照できます。これは機能しますが、ぎこちなく感じます。
解決策 2 : の実装のシングルトン インスタンスを保持するプロジェクトの Application サブクラスを定義しますLoginMgr
。次に、 は Application インスタンスからMainActivity
を取得します。LoginMgr
テスト中にActivityUnitTestCase<MainActivity>
、モック LoginMgr を参照するモック アプリケーションを挿入するために使用できます。コード スニペットは次のとおりです。
主な用途: (必ずAndroidManifest.xml
含む<Application android:name="MainApplication" ...>
)
class MainApplication extends Application {
private static LoginMgr sLoginMgr = new LoginMgrImpl();
public LoginMgr getLoginMgr() {
return sLoginMgr;
}
}
MainActivity は次のように変更する必要があります。
class MainActivity extends Activity {
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
setContentView(R.layout.main);
// 2 lines added
MainApplication aApplication = (MainApplication)getApplication();
LoginMgr aLoginMgr = aApplication.getLoginMgr();
if (aLoginMgr.authenticated()) {
//do something
} else {
//do something else
}
}
}
単体テストは次のようにする必要があります。
public class MainActivityTest extends ActivityUnitTestCase<MainActivity> {
public MainActivityTest() {
super(MainActivity.class);
}
public void testUseAlternateLoginMgr() {
MainApplication aMockApplication = new MainApplication()
{
@Override
public LoginMgr getLoginMgr() {
return new LoginMgr() {
public boolean authenticated() { {
return true;
}
};
}
};
setApplication(aMockApplication);
Intent aDependencyIntent = new Intent("android.intent.action.MAIN");
Activity aMainActivity = startActivity(aDependencyIntent, null, null);
// verify results
}
}
ハンド コードのモックではなく、モック フレームワークを使用することになると思いますが、これは単なる例です。
解決策2がより良い方法だと思います。ありがとう@yorkw!