2016-09-21 2 views
3

Привет, у меня есть следующая проблема. Я хочу написать андроид-тесты с эспрессо для Ui и для того, чтобы иметь тесты, которые не шелушатся, я хочу издеваться над моим ведущим.Android Test with Dagger mock inject constructor

Я использую Кинжал в приложении. Моя конфигурация выглядит следующим образом:

@Singleton 
@Component(modules = AppModule.class) 
public interface AppComponent { 
    //some injections 
    //some providings 
} 

У меня есть модуль для компонента

@Module 
public class AppModule { 
    //providings for component 
} 

тогда у меня есть также компонент для деятельности с модулем для компонента

@PerActivity 
@Component(dependencies = AppComponent.class, modules = ActivityModule.class) 
public interface ActivityComponent { 
    //inject activites 
    //provide subcomponents for activites 
} 

затем у меня есть подкомпоненты для моих страниц

@PerActivity 
@Subcomponent(modules = InfoModule.class) 
public interface InfoComponent { 
    void inject(DetailActivity activity); 
} 

и модуль для субкомпоненту

@Module 
public class InfoModule { 

    @Provides 
    public DetailPresenter provideDetailPresenter(ShowDetailsUseCase showDetailsUseCase, 
             OtherUseCase getPoisUseCase, 
             AccountManager accountManager, Navigator 
               navigator) { 
     return new DetailPresenter(showDetailsUseCase, otherUseCase, accountManager, navigator); 
    } 
} 

, а затем подробно активность впрыскивает DetailPresenter

public class DetailActivity extends BaseActivity { 

    @Inject 
    DetailPresenter mPresenter; 

    InfoComponent mComponent; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mComponent = getActivityComponent().provideInfoModule(new InfoModule()); 
     mComponent.inject(this); 
     mPresenter.bindView(this); 
     mPresenter.onCreate(new PresenterBundle(getIntent().getExtras(), savedInstanceState)); 
    } 
    //functionality of detailActiviy 
} 

тогда у меня есть ведущий, который использует инъекции конструктора

public class DetailPresenter extends BasePresenter { 


    private ShowDetailsUseCase mDetailsUseCase; 
    private final OtherUseCase getPoisUseCase; 

    private AccountManager accountManager; 
    private Navigator navigator; 

    @Inject 
    public DetailPresenter(ShowDetailsUseCase getDetailsUseCase, OtherUseCase getPoisUseCase, 
    AccountManager 
    accountManager, Navigator navigator) { 
     this.mDetailsUseCase = getDetailsUseCase; 
     this.getPoisUseCase = gotherUseCase; 
     this.accountManager = accountManager; 
     this.navigator = navigator; 
    } 

    @Override 
    public void onCreate(@Nullable PresenterBundle bundle) { 
     super.onCreate(bundle); 
     //other things to do on initialization 
     ((DetailView) getView()).showDetails(getDetailsFromUseCase()); 

    } 
} 

Теперь в тесте Я хочу высмеять докладчика:

@RunWith(AndroidJUnit4.class) 
public class DetailActivityTest { 

    @Rule 
    public final ActivityTestRule<DetailActivity> main = new ActivityTestRule<DetailActivity>(DetailActivity.class, true, false); 

    @Rule 
    public final DaggerMockRule<AppComponent> rule=new EspressoDaggerMockRule(); 

    @Mock 
    DetailPresenter presenter; //does not work because @Inject constructor 


    @Test 
    public void locationTest() { 

     Details details = generateDetails(); 

     launchActivity(); 

     doAnswer(answer -> { 
        activity.showDetails(details); 
        return null; 
       } 

     ).when(presenter).onCreate(any()); 

     //espresso verify afterwards 
    } 
} 

но если я пытаюсь издеваться следующее сообщение об ошибке показывает:

java.lang.RuntimeException: Error while trying to override objects: 
a.b.c.ui.mvp.presenter.DetailPresenter 
You must define overridden objects using a @Provides annotated method instead of using @Inject annotation 

ли кто-то есть идея, как я могу издеваться выступающему даже с @Inject конструктора и зависимостей. Я не хочу издеваться над слоем данных, потому что тогда мне приходится макетировать базу данных, apiClient, cacheData и так далее. И некоторые из datalayer также имеют инъекционные зависимости, поэтому я тоже не могу их издеваться над ними.

Спасибо заранее

ответ

1

DetailPresenter класс создается в InfoModule, так что вам не нужно Inject аннотацию. Ошибка, возникающая из-за использования DaggerMock, вы можете заменить только объекты, созданные в модуле. В вашем примере вы уже создаете его в модуле, вам просто нужно удалить аннотацию Inject.

+0

У меня такая же ошибка, я попытался с удалением Inject, но все равно получаю ту же самую ошибку. Может быть и другая причина, и нам нужно создать правило для каждого модуля активности, как это правило. Правило Публичный финал DaggerMockRule rule = new EspressoDaggerMockRule(); или только для компонента приложения –