构造函数注入模拟对象,必须在构造函数中设置模拟值

Constructor injection with mocked object which has to set mocked value in constructor

我正在尝试模拟一个 class FooB,它有另一个组件 FooA 通过构造函数注入注入。我的问题是,在构造函数 FooB 中,必须设置注入组件 FooA 的值。我的问题我不知道如何模拟 FooA。通常我会在 @BeforeAll 中的注释掉的代码中做一些类似的事情,并用 Mockito.when 模拟值。但是在这个阶段 FooB 已经初始化了。

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { FooB.class })
class FooTest {

  @MockBean
  private FooA fooA;

  @Autowired
  private FooB fooB;

  // @BeforeAll
  // void initMocks() {
  //  when(fooA.getFoo()).thenReturn("foo");
  // }
}

@Component
public class FooB {
  private final String foo;

  public FooB(final FooA fooA) {
    this.foo = fooA.getFoo(); // <- how do I get the mocked value in here?
  }
}

@Component
public class FooA {
  private String foo;

  public String getFoo() {
    return foo;
  }

  public void setFoo(final String foo) {
    this.foo = foo;
  }
}

下面的代码可以解决您正在尝试做的事情(编辑:添加了一个使用 @SrringBootTest 和不使用它的测试用例)

如果不使用 SpringBoot

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {FooB.class, FooTest.TestConfig.class})
class FooTest {

    @Autowired
    private FooB fooB;

    @TestConfiguration
    public static class TestConfig {

        @Bean
        FooA getFooA(){
            FooA fooA = Mockito.mock(FooA.class);
            when(fooA.getFoo()).thenReturn("foo from test");
            return fooA;
        }
        
    }

    @Test
    void testFooB() {
        assertEquals("foo from test", fooB.getFoo());
    }
}

如果使用 SpringBoot

@SpringBootTest
class FooTest {

    @Autowired
    private FooB fooB;

    @TestConfiguration
    public static class TestConfig {

        @MockBean
        private FooA fooA;

        @PostConstruct
        void initMocks() {
            when(fooA.getFoo()).thenReturn("foo from test");
        }

    }

    @Test
    void testFooB() {
        assertEquals("foo from test", fooB.getFoo());
    }
}