spring 中的自注入并使用mockito 进行测试

Muk*_*lan 6 java junit spring mockito spring-boot

我们使用 Spring 5.2.x(带有 Spring Boot 2.3.x)和 Mockito 3.3.x。

我需要@Transactional从我的服务中调用一个方法。因此我不得不求助于自我注入。

@Service
@RequiredArgsCostructor // lombok
public class MyClass {
    private final dep1;
    private final dep2;

    @Autowired
    private MyClass self;

    public void someMethod() {
        self.someTransactionalMethod();
        // do something
    }

    @Transactional
    public void someTransactionalMethod() {
        // do something
    }
}

public class MyClassTest {
    @Mock
    private dep1;
    
    @Mock
    private dep2;

    @InjectMocks
    private MyClass myClass;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void someMethodTest() {
        // NPE when calling self.someTransactionalMethod()
    }
}
Run Code Online (Sandbox Code Playgroud)

从代码来看,我们使用 lombok 进行构造函数注入是相关的。由于显而易见的原因,我无法将实例变量声明selffinal,因此用于@Autowired此变量。该课程运行良好,但我发现单元测试存在问题。

我的问题有两部分 -

  1. 关于我进行自我注入的方式 - 这是进行自我注入的最佳方式吗?Spring框架的作者在最新版本的Spring中是否推荐了其他方法?
  2. Mockito 绝对无法将 self bean 注入到 CUT(被测类)的对象中。有没有办法以干净的方式实现这一点?

我已经考虑过以下几点:

  1. 引入一个 setterself并使用它在 setup 方法中注入 self 。不想仅为测试添加设置器。
  2. 使用ReflectionUtils来设置self. 反射对我来说似乎是不干净的。我更喜欢@Setter这个。
  3. 尝试使用@RunWith(SpringJunit4Runner.class)但失败了,因为我没有创建适当的上下文和内容。

voi*_*ipp 5

在 setUp() 方法中调用 ReflectionTestUtils.setField(myClass, "self", myClass)