Android AsyncTaskのテストを行う

Android

Android AsyncTaskのテストを行う
で検索すると、いろいろと記事が出てきますが、自分でも書いておいたほうがわかりやすいので、書いておきます。

 //テスト対象のアクティビティ
 public class OfferDetailActivity extends UtilsActivity implements
        PostJsonTask.PostJsonTaskCallback, View.OnClickListener {
 
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.offer_detail);
 
    context = this;
  
    user = getIntent().getParcelableExtra("user");
 
    Bundle extras = getIntent().getExtras();
 
    getmOfferId(extras);
 
    if (mOfferId != null) {
 
            HashMap<String, String> data = user.makeDataMap();
            String jsonToServer = new Gson().toJson(data);
            PostJsonTask post_json_task = new PostJsonTask(context, jsonToServer, this);
 
            post_json_task.execute(AppConstants.OFFER_DETAIL_URL + "offer_id=" + mOfferId);
 
       } else {
            Toast.makeText(getApplicationContext(), "エラー パラメーターがありません", Toast.LENGTH_LONG).show();
        }
    }
 //テスト対象のAsyncTask
 public class PostJsonTask extends AsyncTask<String, Void, String> {
 
 
    final String TAG = "PostJsonTask";
    Context localContext;
    private String jsonData = null;
    private PostJsonTaskListener mListener;
    private Exception mError = null;
 
    public PostJsonTask(Context context, String data, PostJsonTaskCallback _callback) {
        localContext = context;
        jsonData = data;
        this.callback = _callback;
    }
 
    private PostJsonTaskCallback callback;
 
    //Activiyへのコールバック用interface
    public interface PostJsonTaskCallback {
 
        void postJsonPreExecute();
        void postJsonPostExecute(String result);
        void postJsonCancel();
 
    }
 
   //テストコードのためだけに利用
    public PostJsonTask(Context context, String data) {
        // Required by the semantics of AsyncTask
        super();
 
        this.localContext = context;
    }
 
    @Override
    public void onPreExecute(){
 
        super.onPreExecute();
        if(callback != null) {
            callback.postJsonPreExecute();
        }
 
    }
 
    @Override
    public String doInBackground(String... params) {
 
        String result = null;
 
        try {
            result = getJson(params[0]);
        } catch (RuntimeException e){
            mError = e;
        }
 
        return result;
 
    }
 
    private String getJson(String address){
        try {
            URL url = new URL(address);
            URLConnection conn = url.openConnection();
            conn.setRequestMethod("POST");
            conn.setInstanceFollowRedirects(false);
            conn.setRequestProperty("Accept-Language", "jp");
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
            OutputStream os = conn.getOutputStream();
            PrintStream ps = new PrintStream(os);
            ps.print(jsonData);
            ps.close();
  
            StringBuffer sb = new StringBuffer();
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = null;
            while ((line = br.readLine())!= null){
                sb.append(line);
            }
 
            br.close();
            return sb.toString();
        } catch (MalformedURLException e) {
            e.printStackTrace();
            throw new IllegalArgumentException("Invalid URL");
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Network error");
        }
    }
 
 
    @Override
    public void onPostExecute(String result) {
 
        super.onPostExecute(result);
 
        Log.d(TAG, result);
 
        if(callback != null) {
            callback.postJsonPostExecute(result);
        }
 
        if (this.mListener != null) {
            this.mListener.onComplete(result, mError);
        }
 
    }
 
    @Override
    public void onCancelled() {
 
        super.onCancelled();
        if(callback != null) {
            callback.postJsonCancel();
        }
 
        if (this.mListener != null) {
            mError = new InterruptedException("AsyncTask cancelled");
            this.mListener.onComplete(null, mError);
        }
    }
 
    //テストのために追加
     public PostJsonTask setListener(PostJsonTaskListener listener) {
        this.mListener = listener;
        return this;
    }
 
   public static interface PostJsonTaskListener {
        public void onComplete(String jsonString,  Exception e);
    }
 
 }
 //テストコード
 public class GetOfferDetailJSONTest extends ActivityInstrumentationTestCase2 {
 
    String mJsonString = null;
    Exception mError = null;
    CountDownLatch signal = null;
    private Activity mActivity;
    private int mOfferId;
    private User mUser;
    private int TEST_OFFER_ID = 107;
 
 
    public GetOfferDetailJSONTest() {
        super(OfferDetailActivity.class);
    }
 
    @Override
    protected void setUp() throws Exception {
 
        signal = new CountDownLatch(1);
 
        mUser = new User.Builder("2", "sakurai", "123456", "", "", "", "", "", "","", 0, 0)
                 .build();
        mOfferId = TEST_OFFER_ID;
 
        mActivity = getActivity();
 
   }
 
    @Override
    protected void tearDown() throws Exception {
 
        signal.countDown();
    }
 
    public void testPreConditions(){
 
        assertNotNull(mActivity);
        assertNotNull(mOfferId);
        assertNotNull(mUser);
 
    }
 
    public void testPostJsonTask() throws InterruptedException {
 
        HashMap<String, String> user_info = mUser.makeDataMap();
 
        Context context = mActivity.getApplicationContext();
        String jsonToServer = new Gson().toJson(user_info);
 
       String url = AppConstants.OFFER_DETAIL_URL + "offer_id=" + mOfferId;
        PostJsonTask task = new PostJsonTask(context, jsonToServer);
        task.setListener(new PostJsonTask.PostJsonTaskListener() {
            @Override
            public void onComplete(String jsonString, Exception e) {
                mJsonString = jsonString;
                mError = e;
                signal.countDown();
            }
        }).execute(url);
        signal.await();
 
        assertNull(mError);
        assertFalse(TextUtils.isEmpty(mJsonString));
 
        assertTrue(mJsonString.startsWith("{    \"res\""));
        assertTrue(mJsonString.endsWith("}"));
 
    }
 }

下記のブログを参考にさせて頂きました。m(_ _)m

http://marksunghunpark.blogspot.jp/2015/05/how-to-test-asynctask-in-android.html

ちなみに、はまっちゃったのはPostJsonTaskから、テストを実行すると何も帰ってこないということ。
理由はわかりませんでした。
しかし、すでにデプリケイトされたDefaultHttpClientを下記のように使っていたんですが

 HttpClient client = new DefaultHttpClient();
 HttpPost post = new HttpPost(params[0]);// in this case, params[0] is URL
 try {
              // set up post data
              StringEntity se = new StringEntity(jsonData, "UTF-8");
               post.setEntity(se);
               post.setHeader("Accept", "application/json");
              post.setHeader("Content-Type", "application/json");

 //あとは省略

これをやめて、上記のように

    URL url = new URL(address);
    URLConnection conn = url.openConnection();
 
    StringBuffer sb = new StringBuffer();
    BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

に変更したら、ちゃんと結果を受け取れるようになりました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です