Spring 启动测试:让@Autowired 在不使用 `SpringRunner` 的情况下工作

Spring Boot test: get @Autowired to work without using `SpringRunner`

我正在 pact 提供程序测试 Spring 引导应用程序中。控制器有两个依赖项,其中一个应该被模拟,另一个不应该被模拟。

因为我正在编写 pact test(我是新手),所以我必须在我的测试 class 之上使用 @RunWith(RestPactRunner.class)

在我的测试中 class 我在我不想模拟的依赖项上使用 @Autowired 但是因为我不能使用 SpringRunner 我的测试不知道如何找到依赖项并将其保留为 null.

这里是 pact 提供商测试:

@RunWith(RestPactRunner.class)
@Provider("provider_name")
@PactFolder("target/pacts")
public class SampleProviderTest {
    private MetadataController metadataController;

    @Mock
    private BlockService blockService; // dependency #1: to be mocked

    @Autowired
    private BlockMapper blockMapper; // dependency #2: to be injected

    @TestTarget
    public final MockMvcTarget target = new MockMvcTarget();

    @Before
    public void before() {
        initMocks(this);
        metadataController = new MetadataController(blockService, blockMapper);
        target.setControllers(metadataController);
    }


    /*
    * you can ignore the rest of this test class
    */


    @State("block info")
    public void blockInfo() {
        Block requestedBlock = new Block();
        when(blockService.getBlockInfo(123L, 12345L, "S1", "B1")).thenReturn(requestedBlock);
    }

}

问题:
- 我如何让这个测试为上面的依赖项 #2 (blockMapper) 选择正确的实现?现在它仍然是空的

使用注释 @RunWith(SpringRestPactRunner.class) 而不是 @RunWith(RestPactRunner.class) 。使用 SpringRestPactRunner 而不是 PactRunner 作为 Junit 的运行程序允许我们使用 spring 测试注释。

@RunWith(SpringRestPactRunner.class)
@Provider("provider_name")
@PactFolder("target/pacts")
public class SampleProviderTest {
    private MetadataController metadataController;

您也可以尝试使用注释 @WebMvcTest(MetadataController.class) 和 springrestpackrunner 来测试您的控制器,您所需要的只是应用程序上下文中的 web 相关组件,其他层 bean 可以被模拟.

在不使用 @Autowired 的情况下努力寻找 BlockMapper(实际实现)之后,我终于使用 mapstructMapper class 来找到我的实现测试,我就是这样做的:

@RunWith(RestPactRunner.class)
@Provider("provider_name")
@PactFolder("target/pacts")
public class SampleProviderTest {
    private MetadataController metadataController;

    @Mock
    private BlockService blockService; // dependency #1: to be mocked

    @TestTarget
    public final MockMvcTarget target = new MockMvcTarget();

    @Before
    public void before() {
        initMocks(this);

        // dependency #2: to be injected
        BlockMapper blockMapper = Mappers.getMapper(BlockMapper.class);

        metadataController = new MetadataController(blockService, blockMapper);
        target.setControllers(metadataController);
    }


    /*
    * removed the remainder...
    */
}

我使用了 @RunWith(SpringRestPactRunner.class) 但它出错了:连接到 localhost:8080,有人知道吗?