【问题标题】:Testing a custom RepositoryRestController that uses a PersistentEntityResourceAssembler测试使用 PersistentEntityResourceAssembler 的自定义 RepositoryRestController
【发布时间】:2017-10-10 03:50:01
【问题描述】:

我有一个RepositoryRestController,它公开了一些持久实体的资源。

我的控制器上有一个方法,它采用PersistentEntityResourceAssembler 来帮助我自动生成资源。

@RepositoryRestController
@ExposesResourceFor(Customer.class)
@RequestMapping("/api/customers")
public class CustomerController {

    @Autowired
    private CustomerService service;

    @RequestMapping(method = GET, value="current")
    public ResponseEntity getCurrent(Principal principal Long id, PersistentEntityResourceAssembler assembler) {
        return ResponseEntity.ok(assembler.toResource(service.getForPrincipal(principal)));
    }
}

(人为的例子,但它节省了我用例的不相关细节的太多细节)

我想为我的控制器编写一个测试(我的真实用例实际上值得测试),并计划使用@WebMvcTest。

所以我有以下测试类:

@RunWith(SpringRunner.class)
@WebMvcTest(CustomerController.class)
@AutoConfigureMockMvc(secure=false)
public class CustomerControllerTest {
    @Autowired
    private MockMvc client;

    @MockBean
    private CustomerService service;

    @Test
    public void testSomething() {
        // test stuff in here
    }

    @Configuration
    @Import(CustomerController.class)
    static class Config {
    }

}

但我得到一个例外说java.lang.NoSuchMethodException: org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.<init>()

可能这里没有正确配置某些东西,因为我缺少整个数据层。有没有办法模拟出PersistentEntityResourceAssembler?还是我可以在这里使用的其他方法?

【问题讨论】:

  • 如果将CustomerController 类公开会发生什么?
  • 抱歉,这是一个 C&P 错误,与这个问题无关(不过很好!)。这里的问题是 spring 认为它需要传递一个 PERA,但没有一个。几乎可以肯定,问题出在我的测试配置上。

标签: java spring spring-data-jpa spring-test spring-rest


【解决方案1】:

我现在结束了:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc

它的缺点是测试将启动完整的 Spring 应用程序上下文(但没有服务器)。

【讨论】:

    【解决方案2】:

    我最终在这里做了一个有点老套的解决方案:

    • 我从控制器方法中删除了PersistentEntityResourceAssembler
    • 我向控制器添加了一个@Autowired RepositoryEntityLinks,并在其上调用linkToSingleResource 以根据需要创建链接。
    • 我在我的测试类中添加了一个@MockBean RepositoryEntityLinks,并将模拟配置为返回一些合理的东西:

      given(repositoryEntityLinks.linkToSingleResource(any(Identifiable.class)))
              .willAnswer(invocation -> {
                  final Identifiable identifiable = (Identifiable) invocation.getArguments()[0];
                  return new Link("/data/entity/" + identifiable.getId().toString());
              });
      

    这远非理想 - 我很想知道是否有办法获得足够的数据层,我可以依赖 PersistentEntityResourceAssembler

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-07
      • 2015-03-16
      • 1970-01-01
      • 1970-01-01
      • 2020-06-11
      • 2021-12-26
      • 2013-08-15
      • 1970-01-01
      相关资源
      最近更新 更多