package com.truckmuncher.app.test.rules;
import android.app.Application;
import android.support.test.InstrumentationRegistry;
import com.truckmuncher.app.App;
import com.truckmuncher.app.dagger.Modules;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import dagger.ObjectGraph;
/**
* @ JUnit 4 Rule to generate a new object graph and replace the one that the {@link App}
* is using. This rule always uses the modules provided by {@link Modules#list(Application)}.
*/
public class GraphReplacementRule implements TestRule {
public GraphReplacementRule(Object... modules) {
App app = App.get(InstrumentationRegistry.getTargetContext());
List<Object> combinedModules = new ArrayList<>(Arrays.asList(Modules.list(app)));
Collections.addAll(combinedModules, modules);
try {
// Use reflection to set the app graph. Not great, but hey, this is Android
Field graphField = App.class.getDeclaredField("objectGraph");
graphField.setAccessible(true);
graphField.set(app, ObjectGraph.create(combinedModules.toArray()));
} catch (NoSuchFieldException ignored) {
throw new AssertionError("The field was probably renamed in the Application class");
} catch (IllegalAccessException ignored) {
throw new AssertionError("We're already setting the field as accessible");
}
}
@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
base.evaluate();
}
};
}
}