Je fais un jeu simple et j'ai quelques questions sur l'installation/test du modèle! J'essaie de suivre un modèle MVP si possible.Comment tester correctement le modèle Android (MVP) dans une configuration de jeu simple?
Ce qui suit est une version simplifiée de certaines de mes classes de modèles, principalement celles traitant de la "logique".
public class GameManager implements LocationManagerDelegate {
private LocationManager mLocationManager;
private BattleManager mBattleManager;
public GameManager(Location initialLocation) {
mLocationManager = new LocationManager(initialLocation, self);
mBattleManager = new BattleManager();
}
public void setLocation(Location location) {
mLocationManager.setLocation(location);
}
public void handleLocationAction(Action action) {
if (action.type == BATTLE) {
mBattleManager.startBattle();
}
}
}
public class LocationManager {
private LocationManagerDelegate mDelegate;
private Location mLocation;
public LocationManager(Location initialLocation, LocationManagerDelegate delegate) {
mLocation = initialLocation;
mDelegate = delegate;
}
public void setLocation(Location location) {
mLocation = location;
Action action = location.getRandomAction();
mDelegate.handleLocationAction(action);
}
}
public interface LocationManagerDelegate {
void handleLocationAction(Action action);
}
public class BattleManager {
public BattleManager() {
}
public void startBattle() {
// Do stuff...
}
}
Je suis intéressé par tester ces classes correctement. Je peux facilement tester LocationManager
et BattleManager
- ils sont séparés, et je peux utiliser des interfaces simulées pour les délégués en cas de besoin (à savoir LocationManagerDelegate
)
Mais qu'en est-GameManager
? Il crée des instances concrètes dans sa propre classe, donc si je voulais tester le flux global de la logique à partir des classes utilisant le GameManager
, il testera en fait GameManager
ainsi que la logique LocationManager
/BattleManager
. Je ne peux pas trouver un moyen propre de le diviser ...
Peut-être que quelque chose comme ceci est-ce plus correct?
public class GameManager implements LocationManagerDelegate {
private ILocationManager mLocationManager;
private IBattleManager mBattleManager;
public GameManager(Location initialLocation, ILocationManager locationManager, IBattleManager battleManager) {
mLocationManager = locationManager;
mLocationManager.setInitialLocation(initialLocation);
mLocationManager.setDelegate(this);
mBattleManager = battleManager;
mBattleManager.setDelegate(this);
}
public void setLocation(Location location) {
mLocationManager.setLocation(location);
}
public void handleLocationAction(Action action) {
if (action.type == BATTLE) {
mBattleManager.startBattle();
}
}
}
public interface ILocationManager {
void setInitialLocation(Location initialLocation);
void setDelegate(LocationManagerDelegate delegate);
void setLocation(Location location);
}
public class LocationManager implements ILocationManager {
private LocationManagerDelegate mDelegate;
private Location mLocation;
public void setInitialLocation(Location initialLocation) {
mLocation = initialLocation;
}
public void setDelegate(LocationManagerDelegate delegate) {
mDelegate = delegate;
}
public void setLocation(Location location) {
mLocation = location;
Action action = location.getRandomAction();
mDelegate.handleLocationAction(action);
}
}
public interface LocationManagerDelegate {
void handleLocationAction(Action action);
}
public interface IBattleManager {
void startBattle();
}
public class BattleManager implements IBattleManager {
public void startBattle() {
// Do stuff...
}
}
Ensuite, chaque fois que nous créons en fait l'instance GameManager
, nous faisons quelque chose comme:
ILocationManager locationManager = new LocationManager();
IBattleManager battleManager = new BattleManager();
Location initialLocation = ...;
GameManager manager = new GameManager(initialLocation, locationManager, battleManager);
Cela me permettrait de mettre en objets fantaisie LocationManager
/BattleManager
, mais ne peut pas être trop grand car cela aussi expose certains des «rouages internes» de la classe GameManager
. Il ne devrait pas nécessairement être des informations publiques que j'ai besoin de passer dans ces autres classes de gestionnaire, etc ...
Alors, que faire de mieux? Des pensées!