java - Java中的模拟工厂模式

标签 java junit mockito factory-pattern

它可能看起来类似于我的 question 。我有一个简单的动物工厂。

public class AnimalFactory {

    public Animal getAnimal(String type) {
        if ("canine".equals(type)) {
            return new Dog();
        } else {
            return new Cat();
        }
    }

}

和类

public interface Animal {
    void makeSound();
}

public class Dog extends Animal {
    void makeSound() {
    }
}

public class Dog extends Animal {
    void makeSound() {
    }
}

我有一些疑问。 AnimalFactory 是否违反了依赖倒置原则?是否可以在不调用实际 DogCat 类的情况下对 AnimalFactory 进行单元测试,或者我是否必须重构我的代码?

最佳答案

如果没有要注入(inject)的依赖项,则不会违反依赖项反转原则。

无论如何,Factory 都是一种创造设计模式,您应该测试它是否确实创建(实例化)了正确的东西。

是的,您应该测试它是否返回 instanceof Doginstanceof Cat 为 true 的对象。

如果您必须在不实际调用 DogCat 的构造函数的情况下测试您的工厂(由于它们所做的初始化),我建议像这样重构工厂类:

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(); }
}

测试看起来像这样:

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();
    }
}

顺便说一句,Factory 模式方法的命名约定是 createXyz 而不是 getXyz

祝你好运。

关于java - Java中的模拟工厂模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28557385/

相关文章:

java - 功能代码上的调试流跟踪抛出 IncompatibleClassChangeError

java - Eclipse 如何实际运行 Junit 测试?

grails - 正确指定在Bamboo上构建的Grails 3的测试报告位置

java - 在静态方法中使用 Powermock 和 mockito 模拟本地范围对象

java - 如何模拟扩展另一个接口(interface)的接口(interface)

java - 在没有js的情况下检测是否安装了flash

java - Hibernate 更新单个列

java - 模拟外部服务返回 null

java - 写入不同文件的 Log4j

java - Spring JPA 和 Couchbase - com.couchbase.client.java.error.ViewDoesNotExistException : View cat/all does not exist