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

eqoofvh9  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(129)

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

@AllArgsConstructor
@Component
public class A {

    private B b;

    public String doSomething() {
        return "Result: " + b.doSomethingElse();
    }
}

@Componenet
public class B {

    private A a;

    @Autowired
    public B(@Lazy final A a) {
        this.a = a;
    }

    public String doSomethingElse() {
        return a.toString();
    }
}

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

@RunWith(MockitoJUnitRunner.class)
public class ATest {

    @InjectMocks
    private A a;

    @Spy
    private B b;

    @Test
    public void testDoSomething() {
        final String result = a.doSomething();
        assertNotNull(result);
    }
}


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

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


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

92vpleto

92vpleto1#

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

class LazyA extends A {
  private A realA;

  public LazyA() { this(null); }
 
  public void setRealA(final A realA) {
    this.realA = realA;
  }

  public String doSomething() {
    return realA.doSomething();
  } 
}

public class ATest {
  @Test
  public void testDoSomething() {
    final LazyA lazyA = new LazyA();
    final B b = new B(lazyA);
    final A a = new A(b);
    lazyA.setRealA(a);

    final String result = a.doSomething();
    assertNotNull(result);
  }
}

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

相关问题