【问题标题】:Mockito: How to mock javax.inject.Provider-created prototype beans?Mockito:如何模拟 javax.inject.Provider 创建的原型 bean?
【发布时间】:2018-03-20 13:09:18
【问题描述】:

我有一个创建原型 bean 的单例 Spring bean;这些是从javax.inject.Provider 字段中检索到的:

@Component
public class MySingleton {
    @Autowired
    private javax.inject.Provider<MyPrototype> prototypeFactory;

    public void doStuff() {
        MyPrototype bean = prototypeFactory.get();
        bean.invoke();
    }
}

@Component
@Scope("prototype")
public class MyPrototype {
    public void invoke() {}
}

现在我想为 Singleton 创建一个 JUnit-Test:

@Mock 
MyPrototype prototype;
@InjectMocks 
MySingleton sut;
@Test
public void testPrototype() {
    sut.doStuff();
    verify(prototype, times(1)).invoke();
}

但是可以理解的是,这并没有正确设置 Singleton 的 Provider

有没有办法做到这一点?我想避免创建一个创建 Prototype 实例的 Singleton Factory bean。

或者,是否可以优雅地为 Singleton 使用 @Lookup-factory 方法?我还没有研究过。

【问题讨论】:

    标签: java spring unit-testing junit mockito


    【解决方案1】:

    我会存根该Provider 并使其每次使用在每次测试之前调用的@Before 方法都返回prototypeMock

    @Mock
    private javax.inject.Provider<MyPrototype> prototypeFactoryStub;
    
    @Mock 
    MyPrototype prototypeMock;
    
    @InjectMocks 
    MySingleton sut;
    
    @Before
    public void init(){
       MockitoAnnotations.initMocks(this); // optional
    
       when(prototypeFactoryStub.get()).thenReturn(prototypeMock);
    }
    
    @Test
    public void testPrototype() {
        sut.doStuff();
        verify(prototypeMock, times(1)).invoke();
    }
    

    如果您需要进一步阅读,我已经在Mockito Stubbing 上写了一篇文章。

    【讨论】:

    【解决方案2】:
    @Mock 
    MyPrototype prototype;
    
    @Spy
    Provider<MyPrototype> prototypeProvider = new Provider<MyPrototype>() {
        public MyPrototype get() {return prototype;}
    };
    
    @InjectMocks 
    MySingleton sut;
    

    【讨论】:

      猜你喜欢
      • 2018-11-01
      • 1970-01-01
      • 2015-01-14
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 2013-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多