【问题标题】:How to mock an interface with two different implementation [duplicate]如何模拟具有两种不同实现的接口[重复]
【发布时间】:2018-02-27 05:35:48
【问题描述】:

我有一个需要测试的类,它有两个不同类的实例,但接口相同。代码是这样的,

要测试的类:

@Service
public class MainClass {
   @Resource(name = "aClass")
   private IClass instance1;
   @Resource(name = "bClass")
   private IClass instance2;
}

其他类:

@Service("aClass")
public class A implements IClass {}

@Service("bClass")
public class B implements IClass {}

我的单元测试:

public MainClassTest {
   @InjectMocks
   private MainClass mainClass;

   @Mock
   private IClass instance1;
   @Mock
   private IClass instance2;

   @Test
   public void test() {...}
}

当我运行测试时,instance1 和 instance2 都为 null,因为它们没有被模拟。当接口只有一个实现时,就不会发生这种情况。

知道如何处理吗?

谢谢, 安杰洛

【问题讨论】:

    标签: java spring unit-testing junit mockito


    【解决方案1】:

    我认为您看到的行为可能是 Mockito 的已知行为;有一个 open issue describe here 与 Mockito 对 @InjectMocks 的处理有关,其中两个实例具有相同的模拟类型。

    因此,您可以使用“老式”方式创建 MainClass 的实例,而不是依赖它,例如在@Before 方法中。例如:

    private MainClass mainClass;
    
    @Before
    public void setup() {
        IClass instance1 = mock(IClass.class); 
        IClass instance2 = mock(IClass.class);
    
        mainClass = new MainClass(instance1, instance2);
    }
    

    【讨论】:

    • 无论如何我都会建议您始终这样做。在没有 setter 或构造函数注入的情况下注入私有字段会很快变得混乱。
    • 这是一种在工作时有用但在出错时痛苦的东西。就我而言,我还不相信改用@InjectMocks
    • 是的,这通常是设计不佳的标志。我几乎希望 Spring 不允许字段级注入。我曾经在一个 100% 现场级注入的大型项目中,它似乎总是导致只增加一个字段。最终,最终出现了具有 10 多个依赖项的类,最糟糕的是大约 20 个。我认为构造函数注入会迫使您保持依赖项的可管理性。带有 20 个参数的构造函数看起来是错误的 :-)
    • “再多一个字段”...可能发生的最坏情况是什么 ;)
    【解决方案2】:

    尝试使用instance1 = mock(aClass.class);instance2 = mock(bClass.class);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 2018-01-01
      • 1970-01-01
      相关资源
      最近更新 更多