簡體   English   中英

Android測試:用Mockito挖掘改造

[英]Android Tests: Stubbing out Retrofit with Mockito

在我的MainActivity我有一個名為getAPI的方法,它返回一個OTBServiceWrapper 這用於設置用於調用API的改進。

在我的MainActivityTest文件中,我試圖找出getApi方法正在進行的new OTBService().getService()調用,這樣我就可以返回一個MockedOTBService ,它將客戶端更改為返回json的自定義客戶端。

MockedOTBService如果我不得不在MockedOTBService放置一個記錄器但是它也會通過並調用真正的api,那么當前的實現將是MockedOTBService ,這在測試中不是我想要的。

我試圖使用Mockito存根Retrofit API調用並返回json 我似乎無法理解為什么存根被調用尚未存在問題的方法。

筆記:

  1. 我正在使用ActivityInstrumentationTestCase2
  2. 我只運行一次測試
  3. 如果我添加一個verify(mockedOTBService, atLeastOnce()).getService(); 據說它從未被稱為。
  4. 如果我更改when...thenReturn使用mMainActivity = spy(getActivity())則沒有更改並且會調用真正的API。

Logcat輸出

Logger﹕ MockedOTBService was called // Mock is called
Logger﹕ Real OTBService was called // Real API is called
Logger﹕ MainActivity getAPI method class is "$Proxy1" // Mock is shown in MainActivity
Logger﹕ RealAPIResponse JSON Parsed ID: 266 // Real API response returned

真正的流量

MainActivity.onCreate()> OTBService.getService()> OTBServiceWrapper.createSearch(...)

試圖在測試中實現

MainActivity.onCreate()> MockedOTBService.getService()> OTBServiceWrapper.createSearch(...)

MainActivity.java

public class MainActivity extends Activity {
  private OTBServiceWrapper serviceWrapper;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    getApi().createSearch(...)
  }

  public OTBServiceWrapper getApi() {
    return new OTBService().getService();
  }
}

OTBService.java

public class OTBService {
  public OTBServiceWrapper getService() {
    RestAdapter restAdapter = new RestAdapter.Builder()
        .setEndpoint(Constants.API_URL)
        .build();

    return restAdapter.create(OTBServiceWrapper.class);
  }
}

OTBServiceWrapper.java

public interface OTBServiceWrapper {
  @POST(Constants.API_SEARCHES_POST_URL)
  void createSearch(@Body Request request, Callback<Request.Response> callback);
}

MainActivityTest.java

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
  private OTBService mMockedOTBService;
  private MainActivity mMainActivity;
  private View mSearchButton;

  public MainActivityTest() { super(MainActivity.class); }

  @Override
  protected void setUp() throws Exception {
    super.setUp();

    setActivityInitialTouchMode(true);

    System.setProperty("dexmaker.dexcache", getInstrumentation().getTargetContext().getCacheDir().getPath());

    mMockedOTBService = mock(OTBService.class);
    when(mMockedOTBService.getService()).thenReturn(new MockedOTBService(getInstrumentation().getContext()).getService());

    mMainActivity = getActivity();

    mSearchButton = mMainActivity.findViewById(R.id.AbSearchButton);
    mYourHolidayButton = mMainActivity.findViewById(R.id.AbYourHolidayButton);
  }

  public void testButtonActions() {
    TouchUtils.clickView(this, mSearchButton);
    ...
  }
}

MockedOTBService.java

public class MockedOTBService {
  private Context context;

  public MockedOTBService(Context context) { this.context = context; }

  public OTBServiceWrapper getService() {
    RestAdapter restAdapter;

    restAdapter = new RestAdapter.Builder()
        .setClient(new LocalJsonClient(context))
        .setEndpoint(Constants.API_TEST_URL)
        .build();

    return restAdapter.create(OTBServiceWrapper.class);
  }
}

LocalJsonClient.java

@SuppressLint("DefaultLocale")
public class LocalJsonClient implements Client { ... }

的build.gradle

dependencies {
    androidTestCompile 'com.google.dexmaker:dexmaker:1.0'
    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0'
}

通過允許Activity設置服務,無需模擬您的請求。

MainActivity ,為服務創建一個類變量和一個類設置器。 它必須是類范圍,以防止在將服務設置為您希望的服務之前調用OnCreate方法。 還要創建一個實例getter來設置服務(如果還沒有)。

在您調用getActivity()之前的測試中,將服務設置為您的模擬服務。 (也許考慮將其移到支持對象)。

MainActivity.java

public class MainActivity extends Activity {
  private static OTBServiceWrapper serviceWrapper;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    getServiceWrapper.createSearch(...)
  }

  public OTBServiceWrapper getServiceWrapper() {
    if (serviceWrapper == null) {
      MainActivity.setServiceWrapper(new OTBService().getService());
    }

    return serviceWrapper;
  }

  public static void setServiceWrapper(OTBServiceWrapper serviceWrapper) {
    MainActivity.serviceWrapper = serviceWrapper;
  }
}

MainActivityTest.java

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
  private MainActivity mMainActivity;

  public MainActivityTest() { super(MainActivity.class); }

  @Override
  protected void setUp() throws Exception {
    super.setUp();

    setActivityInitialTouchMode(true);

    MainActivity.setServiceWrapper(
      new MockedOTBService(getInstrumentation().getContext()).getService()
    );

    mMainActivity = getActivity();
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM