0

我刚刚开始在 Android 上进行单元测试。我试过测试一个简单的计算器应用程序,但我遇到了一个关于注入模拟的问题。

据我了解,有两种注入模拟的方法。使用依赖注入或使用@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 时,会使用存储在 Vars 中的默认值而不是 mockVar,这可能意味着模拟变量没有正确注入。谁能指出我哪里出错了?

编辑:使用 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 引入的部分模拟的概念。

您需要在 Activity 中注入这个模拟的 Var 依赖项,这很困难,因为 Android 正在管理 Activity 的整个生命周期。因此,为了达到您想要的结果,您可以使用 Square 的 Dagger 框架,或者如果您不想在您的应用程序中引入第三方依赖项,您可以使用服务定位器模式。

这里有一篇更详细的关于服务定位器模式的文章,用于在你的 Activity 中注入依赖项: 使用服务定位器模式改进 Android 测试

于 2016-01-15T21:54:04.967 回答