It may look similar to my question. I have a simple animal factory.
public class AnimalFactory {
public Animal getAnimal(String type) {
if ("canine".equals(type)) {
return new Dog();
} else {
return new Cat();
}
}
}
and class for
public interface Animal {
void makeSound();
}
public class Dog extends Animal {
void makeSound() {
}
}
public class Dog extends Animal {
void makeSound() {
}
}
I have some doubts. Does AnimalFactory
violate the dependency inversion principle? Is it possible to unit test AnimalFactory
without making calls to the actual Dog
and Cat
classes or do I have to refactor my code?
You're not violating the dependency inversion principle if there are no dependencies to inject.
In any case the Factory
is a creational design pattern and you should test that it does indeed create (instantiate) the right things.
Yes, you should test that it does return objects where instanceof Dog
and instanceof Cat
are true.
If you must test your factory without actually calling the constructors of Dog
and Cat
(due to the initialization that they do), I suggest refactoring the factory class like this:
public class AnimalFactory {
public Animal createAnimal(String type) {
if ("canine".equals(type)) {
return createDog();
} else {
return createCat();
}
}
Dog createDog() { return new Dog(); }
Cat createCat() { return new Cat(); }
}
And the test would look like this:
public class AnimalFactoryTest {
@Test
public void testCreateDog() throws Exception {
AnimalFactory mockFactory = mock(AnimalFactory.class);
when(mockFactory.createAnimal(anyString())).thenCallRealMethod();
mockFactory.createAnimal("canine");
verify(mockFactory).createDog();
}
@Test
public void testCreateCat() throws Exception {
AnimalFactory mockFactory = mock(AnimalFactory.class);
when(mockFactory.createAnimal(anyString())).thenCallRealMethod();
mockFactory.createAnimal("cat");
verify(mockFactory).createCat();
}
}
Incidentally, the naming convention for Factory
pattern methods are createXyz
rather than getXyz
.
Good luck.