I create ship objects with my ShipFactory, but my ships have a dependency on my Accelerometer class (just a wrapper for the Android accelerometer). So I have my factory, when it's building a ship, pass in an accelerometer to the ships constructor.
This is my ShipFactory:
public class ShipFactory {
private int screenX;
private int screenY;
private Context context;
private Bitmap bitmap;
// How can I mock this from in my factory?
private Accelerometer accel;
private Ship ship;
public ShipFactory(Context context){
this.context = context;
accel = new Accelerometer(context);
}
public Ship makeShip(String shipType){
bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.myship)
ship = new Ship(context,screenX,screenY,bitmap,accel);
return ship;
}
}
So I make a ship like this:
ShipFactory shipFactory = new ShipFactory(context);
ship = shipFactory.makeShip("enemy");
But now let's say I want to unit my ship class and I want to mock out these dependencies. Context is easy to mock because I can just pass a mock context to my factory, but my factory still depends on accelerometer.
For unit testing this should I be creating a new factory just for testing? Or is it a benefit of using a factory that in my unit test I could forgo the factory all together and directly create a new ship by passing my mocks to in the ships constructor?
Your ShipFactory
depends on Ship
. However Ship
does not depend on ShipFactory
. Test your Ship
independently of the ShipFactory
. Since there's no dependency, there is no need for dependency injection.
Now later on when your factory gets bigger, you should write tests specifically for your factory. To accomplish that, I would suggest extracting all of the dependencies and injecting them in the constructor. You can overload the constructor to help you with this:
// you can use this for convenience
public ShipFactory(Context context){
this(new BitmapProvider(context), new Accelerometer(context));
}
// use this for testing because you can provide mock versions
public ShipFactory(BitmapProvider provider, Accelerometer accel){
this.provider = provider;
this.accel = accel;
}
// wrapping BitmapFactory because it is a buncha static methods... aka a pain to mock
class BitmapProvider {
Context context;
public BitmapProvider(Context context){
this.context = context;
}
public Bitmap getBitmap(int resId){
return BitmapFactory.decodeResource(context.getResources(), resId);
}
}