0

Androidで単体テストを開始しました。簡単な電卓アプリをテストしてみましたが、モックの注入に関する問題に悩まされています。

私の理解によれば、モックを注入するには2つの方法があります。依存性注入を使用するか、 や などの注釈を使用@Mock@InjectMocksます。

だからここに私の問題があります:

私の計算機クラスは、使用する変数のデフォルト値を保持する別のクラスVarsを使用します。これは、デフォルトの変数の代わりに他の変数を使用できるように、モックしたいクラスです。

@RunWith(MockitoJUnitRunner.class)
public class CalcActivityTest extends ActivityUnitTestCase<CalcActivity> {

private Intent in;
private Button btnAdd,btnSub,btnMul,btnDiv,btnDef;
private TextView res;
@InjectMocks
private CalcActivity mActivity;
@Mock
private Vars mockVar;


public CalcActivityTest() {
    super(CalcActivity.class);
}

@Before
protected void setUp() throws Exception{

    super.setUp();
    in = new Intent(getInstrumentation().getTargetContext(),CalcActivity.class);
    in.putExtra("num1", 20.0);
    in.putExtra("num2",20.0);
    startActivity(in, null, null);
    mockVar = mock(Vars.class);
    mockVar.setn1(20);
    mockVar.setn2(40);

    mActivity = getActivity();

}

ただし、いずれかの操作にmockVarを使用しようとすると、mockVarの代わりにVars内に保存されているデフォルト値が使用されます。これは、おそらくモックされた変数が適切に注入されていないことを意味します. 誰かが私が間違っていた場所を指摘できますか?

編集: CalcActivity からのコードで質問を更新する

package com.example.advancedcalc;

import com.example.advancedcalc.R;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class CalcActivity extends Activity implements OnClickListener {

private Button btnAdd,btnSub,btnMul,btnDiv,btnDefault;
private TextView res;

private double n1,n2;

private Vars var;

public CalcActivity(Vars var){
    this.var  = var;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_calc);

    btnAdd = (Button) findViewById(R.id.add);
    btnSub = (Button) findViewById(R.id.sub);
    btnMul = (Button) findViewById(R.id.mul);
    btnDiv = (Button) findViewById(R.id.div);

    btnDefault = (Button) findViewById(R.id.btnDef);

    res = (TextView) findViewById(R.id.res);

    Bundle extras = getIntent().getExtras();
    n1 = extras.getDouble("num1");
    n2 = extras.getDouble("num2");

    var = new Vars();

    btnAdd.setOnClickListener(this);
    btnSub.setOnClickListener(this);
    btnMul.setOnClickListener(this);
    btnDiv.setOnClickListener(this);

    btnDefault.setOnClickListener(this);

}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.calc, menu);
    return true;
}

@Override
public void onClick(View v) {
    switch(v.getId()){
    case R.id.add: 
        res.setText(String.valueOf(add(n1,n2)));
        break;
    case R.id.sub: 
        res.setText(String.valueOf(sub(n1,n2)));
        break;
    case R.id.mul: 
        res.setText(String.valueOf(mul(n1,n2)));
        break;
    case R.id.div: 
        res.setText(String.valueOf(div(n1,n2)));
        break;
    case R.id.btnDef:
        n1 = var.getn1();
        n2 = var.getn2();
    }

}

public double add(double n1,double n2){
    return n1+n2;
}
public double sub(double n1,double n2){
    return n1-n2;
}
public double mul(double n1,double n2){
    return n1*n2;
} 
public double div(double n1,double n2){
    return n1/n2;
}
}
4

2 に答える 2

3
  1. @Mock を Vars クラスに既に使用しているため、使用する必要はありません -

    mockVar = mock(Vars.class);

  2. モック オブジェクトの呼び出しをスタブする必要があります。それ以外の -

    mockVar.setn1(20); mockVar.setn2(40);

ゲッターをスタブする必要があります (Vars クラスに getn1() のようなメソッドがあると確信しています) -

Mockito.when(mockVar.getn1()).thenReturn(20);
Mockito.when(mockVar.getn2()).thenReturn(40);

そして、テストを書きます。

于 2013-08-13T06:59:52.833 に答える
0

これは、Mockito によって導入された部分モックの概念を人々が混同する古典的な問題です。

このモック化された Var 依存関係をアクティビティに挿入する必要がありますが、Android がアクティビティのライフサイクル全体を管理しているため、これは困難です。したがって、目的の結果を達成するには、Square の Dagger フレームワークを使用するか、アプリにサード パーティの依存関係を導入したくない場合は Service Locator パターンを使用します。

アクティビティに依存関係を注入するための Service Locator パターンの詳細な記事は次のとおりです: Service Locator パターンを使用した Android テストの改善

于 2016-01-15T21:54:04.967 に答える