我有一个抽象的accountRequiredActivity,它如下所示(工作正常):

public abstract class AccountRequiredActivity extends LifecycleActivity {

    @Inject
    ViewModelProvider.Factory viewModelFactory;

    private AccountViewModel accountViewModel;

    public abstract void doOnCreate(Bundle savedInstanceState);
    public abstract void doOnResume();

    @Override
    protected final void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loading_app);
        AndroidInjection.inject(this);
        accountViewModel = ViewModelProviders.of(this, viewModelFactory).get(AccountViewModel.class);

        if(!accountViewModel.isAuthenticated()) {
            redirectToLogin();
        } else {
            doOnCreate(savedInstanceState);
        };

    }

    @Override
    protected void onResume() {
        super.onResume();
        if(!accountViewModel.isAuthenticated()) {
            redirectToLogin();
        } else {
            doOnResume();
        };
    }

    private void redirectToLogin() {
        Intent intent = new Intent(this, LoginActivity.class);
        startActivity(intent);
    }

}

测试期间的问题是,我无法设置活动的viewModelFactory
当一个活动有片段时,我可以这样做:
@Before
public void init() {
    LoginFragment fragment = LoginFragment.newInstance();
    viewModel = mock(AccountViewModel.class);
    when(viewModel.getAuthenticatedUserResource()).thenReturn(authenticatedUser);

    fragment.viewModelFactory = ViewModelUtil.createFor(viewModel);
    activityRule.getActivity().setFragment(fragment);
}

但在这种情况下,问题是我在测试中使用了此选项(HomeActivity扩展了AccountRequiredActivity):
@Rule
public ActivityTestRule<HomeActivity> activityTestRule = new ActivityTestRule<>(HomeActivity.class, true, false);

因此无法动态设置viewModelFactory,因为onCreate会立即被调用。似乎没有办法在调用onCreate之前访问activity对象。
如何解决这个问题?
注:我使用匕首2.11与雄激素注射。
另请参阅我昨天发布的问题,以获取后续信息:
Inject ViewModelFactory.Provider in activity for espresso testing

最佳答案

您可以创建自己的testrule

public class MyCustomRule<A extends MainActivity> extends ActivityTestRule<A> {
    public MyCustomRule(Class<A> activityClass) {
        super(activityClass);
    }

    @Override
    protected void beforeActivityLaunched() {
        super.beforeActivityLaunched();
        // Maybe prepare some mock service calls
        // Maybe override some depency injection modules with mocks
    }

    @Override
    protected Intent getActivityIntent() {
        Intent customIntent = new Intent();
        // add some custom extras and stuff
        return customIntent;
    }

    @Override
    protected void afterActivityLaunched() {
        super.afterActivityLaunched();
        // maybe you want to do something here
    }

    @Override
    protected void afterActivityFinished() {
        super.afterActivityFinished();
        // Clean up mocks
    }
}

并设置为ActivityTestRule
@Rule
public ActivityTestRule<MainActivity> testRule = new MyCustomRule<>(MainActivity.class);

beforeActivityLaunched()中,您可以注入您的viewModelFactory
more here

10-08 19:04