2014-04-07 16 views
8

Trong số MainActivity Tôi có một phương pháp gọi là getAPI trả về một OTBServiceWrapper. Điều này được sử dụng để thiết lập trang bị thêm để gọi đến API.Android Tests: Stubbing out Retrofit với Mockito

Trong file MainActivityTest của tôi, tôi đang cố gắng để còn sơ khai ra new OTBService().getService() gọi là phương pháp getApi đang thực hiện vì vậy tôi có thể trở lại một MockedOTBService làm thay đổi khách hàng sang một tùy chỉnh mà trở json.

Hiện tại, việc triển khai hiện tại sẽ là MockedOTBService nếu tôi phải đặt nhật ký trong phạm vi MockedOTBService nhưng cũng rơi qua và gọi api thực, không muốn tôi muốn thử nghiệm.

Tôi đang cố gắng khai báo các cuộc gọi API trang bị thêm bằng Mockito và trả lại json. Tôi dường như không thể hiểu tại sao cái cuống được gọi là chưa được đưa vào phương pháp.

Ghi chú:

  1. Tôi đang sử dụng ActivityInstrumentationTestCase2
  2. tôi chỉ chạy một thử nghiệm
  3. Nếu tôi thêm một verify(mockedOTBService, atLeastOnce()).getService(); là nói nó chưa từng được gọi.
  4. Nếu tôi thay đổi when...thenReturn để sử dụng mMainActivity = spy(getActivity()) thì không thay đổi và API thực được gọi.

Logcat Output

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 

Bất luồng

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

Đang cố gắng đạt được trong các thử nghiệm

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); 
} 

MainAc tivityTest.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' 
} 

Trả lời

6

Hủy bỏ sự cần thiết của chế giễu yêu cầu của bạn bằng cách cho phép các Hoạt động để thiết lập các dịch vụ.

Trong số MainActivity tạo biến lớp và trình cài đặt lớp cho dịch vụ. Nó cần phải là một phạm vi lớp để ngăn chặn các phương pháp OnCreate được gọi trước khi bạn đã đặt dịch vụ cho những gì bạn muốn nó được. Cũng tạo ra một getter dụ mà đặt dịch vụ nếu bạn chưa có.

Trong thử nghiệm của bạn trước khi bạn gọi getActivity() đặt dịch vụ làm dịch vụ giả lập của bạn. (Có thể suy nghĩ về việc di chuyển điều này ra một đối tượng hỗ trợ).

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(); 
    } 
}