Mockito和循环依赖:如何实现实际的类实现

eqoofvh9  于 2024-01-07  发布在  其他
关注(0)|答案(1)|浏览(192)

下面的类相互引用,形成循环依赖:

  1. @AllArgsConstructor
  2. @Component
  3. public class A {
  4. private B b;
  5. public String doSomething() {
  6. return "Result: " + b.doSomethingElse();
  7. }
  8. }
  9. @Componenet
  10. public class B {
  11. private A a;
  12. @Autowired
  13. public B(@Lazy final A a) {
  14. this.a = a;
  15. }
  16. public String doSomethingElse() {
  17. return a.toString();
  18. }
  19. }

字符串
我需要测试类A并确保类B的实际实现被调用:

  1. @RunWith(MockitoJUnitRunner.class)
  2. public class ATest {
  3. @InjectMocks
  4. private A a;
  5. @Spy
  6. private B b;
  7. @Test
  8. public void testDoSomething() {
  9. final String result = a.doSomething();
  10. assertNotNull(result);
  11. }
  12. }


@Spy不工作,我总是得到以下错误:

  1. Unable to initialize @Spy annotated field 'b'.
  2. Please ensure that the type 'B' has a no-arg constructor.
  3. org.mockito.exceptions.base.MockitoException: Unable to initialize @Spy annotated field 'b'.
  4. Please ensure that the type 'B' has a no-arg constructor.


我可以使用@Mock.但是我需要模拟预期的结果,而我需要调用实际的实现(这就是我使用@Spy的原因)。
有什么办法可以解决这个问题吗?非常感谢:-)

92vpleto

92vpleto1#

做Spring对@Lazy依赖所做的事情:不要直接注入依赖,而是一个代理示例,它允许惰性地设置依赖。你可以通过依赖接口而不是具体的类来避免一些问题。

  1. class LazyA extends A {
  2. private A realA;
  3. public LazyA() { this(null); }
  4. public void setRealA(final A realA) {
  5. this.realA = realA;
  6. }
  7. public String doSomething() {
  8. return realA.doSomething();
  9. }
  10. }
  11. public class ATest {
  12. @Test
  13. public void testDoSomething() {
  14. final LazyA lazyA = new LazyA();
  15. final B b = new B(lazyA);
  16. final A a = new A(b);
  17. lazyA.setRealA(a);
  18. final String result = a.doSomething();
  19. assertNotNull(result);
  20. }
  21. }

字符串
更好的是:不要编写具有循环依赖关系的代码。

展开查看全部

相关问题