您好我有以下问题。我想用Ui为esi编写android测试,并且为了进行非片状的测试,我想模仿我的演示者。
我在App中使用Dagger。我的配置如下:
/**
* returns default value if column is not present in resultset
*
* @param rs
* @param columnLabel
* @param defaultValue
* @return
*/
@SuppressWarnings("unchecked")
private static <T> T getValueFromResultSet(final ResultSet rs,
String columnLabel, T defaultValue) {
try {
return (T) rs.getObject(columnLabel);
} catch (SQLException e) {
return defaultValue;
}
}
我有一个组件模块
@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);
}
然后详细活动注入DetailPresenter
@Module
public class InfoModule {
@Provides
public DetailPresenter provideDetailPresenter(ShowDetailsUseCase showDetailsUseCase,
OtherUseCase getPoisUseCase,
AccountManager accountManager, Navigator
navigator) {
return new DetailPresenter(showDetailsUseCase, otherUseCase, accountManager, navigator);
}
}
然后我有使用构造函数注入的演示者
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
}
}
有人知道我是如何使用@Inject构造函数和依赖项来模拟演示者的。 我不想模拟数据层,因为那时我必须模拟数据库,apiClient,cacheData等。而且一些数据层也有注入依赖项,所以我也不能嘲笑它们。
提前谢谢
答案 0 :(得分:1)
DetailPresenter
类是在InfoModule
中创建的,因此您不需要Inject
注释。您得到的错误是因为使用DaggerMock只能替换模块中创建的对象。在您的示例中,您已经在模块中创建它,您只需要删除Inject
注释。