Макет веб-сервиса, созданный на основе модифицированного RestAdapter и внедренный через Dagger2.

Я использую Retrofit и внедряю классы/интерфейсы RestAdapter и WebService через Dagger2.

В тестах я издеваюсь над своим классом веб-сервиса как MockWebService200 implements WebService, и я получаю это исключение от Retrofit

java.lang.IllegalArgumentException: Only interface endpoint definitions are supported.
        at retrofit.Utils.validateServiceClass(Utils.java:102)
        at retrofit.RestAdapter.create(RestAdapter.java:193)

Вот класс интерфейса для WebService

public interface WebService {

@FormUrlEncoded
@POST("/loginByEmail")
void loginByEmail (@Field("emailaddress") String email,
                   @Field("password") String password,
                   @Field("checksum") String checksum,
                   Callback<ServiceModel<User>> callback);
}

А вот и мой MockWebService200 класс

public class MockWebService200 implements WebService {
    @Override
    public void loginByEmail (@Field("emailaddress") String email,
                          @Field("password") String password,
                          @Field("checksum") String checksum,
                          Callback<ServiceModel<User>> callback) {
    ServiceModel<User> userModel = getServiceModel( getUser() );
    callback.success( userModel, null );
    }

    @Override public <T> ServiceModel<T> getServiceModel (T model) {
        // Skipped
    }

    @Override public User getUser () {
    // Skipped
    }
    }

getUser() и getServiceModel() здесь пропущены.

Вот код для @module, который предоставляет зависимости

@Module
@Singleton
public class ApiModule {
    @Provides
    @Singleton RestAdapter provideRestAdapter () {
        RestAdapter.Builder builder = new RestAdapter.Builder()
                .setEndpoint( "some_url" )
                .setClient( /*OkHttpClient*/ );

        return builder.build();
    }

    @Provides
    @Singleton WebService provideWebService (RestAdapter restAdapter) {
        return restAdapter.create( MockWebService200.class );
    }
}

Вопросы:

1- Как это исправить?

2- Правилен ли мой подход к имитированию веб-сервисов с помощью полиморфизма и какие альтернативы я могу здесь использовать?


person Hassan Jawed    schedule 27.08.2015    source источник
comment
Используете ли вы RestAdapter для создания экземпляра своего издевательского класса? Мокабельный класс не нужно создавать путем модификации, поскольку вы предоставляете реализацию вместо модификации.   -  person AlexWalterbos    schedule 27.08.2015
comment
Да, я использую RestAdapter и предоставляю MockWebService200.class в своем builder().create() как RestAdapter.builder().create(MockWebService200.class). Я также добавлю код провайдера в свой вопрос.   -  person Hassan Jawed    schedule 27.08.2015


Ответы (1)


Вы не можете попросить RestAdapter реализовать класс, потому что класс является реализацией. Вы должны создать его отдельно в своем тесте, используя конструктор, возможно, только пустой. Таким образом, вместо того, чтобы внедрять его через Dagger, вы просто создаете свой собственный экземпляр с помощью new MockWebService200(). Однако вам также придется реализовать getServiceModel().

person AlexWalterbos    schedule 27.08.2015
comment
Я отредактировал свой вопрос и предоставил код для создания экземпляра RestAdapter, если я создам новый экземпляр RestAdapter, скажем, MockedRestAdapter в своем тестовом классе, как я могу заставить свои фрагменты использовать этот MockedRestAdapter? Более того, getServiceModel() здесь пропущено, потому что я чувствовал, что это выходит за рамки этого вопроса. - person Hassan Jawed; 27.08.2015
comment
Причина, по которой вы издеваетесь над WebService, заключается в том, что вы не хотите тестировать эту часть своего кода; вы хотите, чтобы у него было гарантированное предсказуемое поведение. Вот почему вы реализуете свой MockWebService200. Это означает, что вам больше не следует использовать RestAdapter для его создания, потому что вы не хотите его тестировать. Так; бросить RestAdapter часть вашего класса. В своем тесте получите издевательскую версию вашего WebService, используя WebService mockedService = new MockWebService200(), и работайте с ней вместо внедренной реализации WebService, созданной RestAdapter. - person AlexWalterbos; 27.08.2015
comment
Я вижу, позвольте мне попробовать это. Хорошее предложение. - person Hassan Jawed; 27.08.2015