无法在Spring Reactive中模拟我的服务的方法

时间:2018-10-16 14:17:13

标签: spring testing documentation

我正在尝试使用Spring react开发一个聊天应用程序。基本上,我有一个 CommentRestController ,其中具有 postComment 和列表方法。 -我已经删除了list方法和其他一些不必要且无关的方法,因为我现在不关注它们-在这里;

var cors = require('cors');

app.options('*', cors()); 

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-  With, Content-Type, Accept");
    next();   
});

// define a simple route
app.get('/', (req, res) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 
    res.json({"message": "Welcome to Application"});
});

app.listen(3002, () => {
    console.log("Server is listening on port 3002");
});

现在,我正在尝试编写此Controller的Documentation测试。我遇到的问题是,我无法模拟我的commentService的 save 方法。它实际上是在模拟实例,而不是在模拟方法。

这是我的文档测试课程。

@RestController
@RequiredArgsConstructor
@RequestMapping("/chat/comment")
public class CommentRestController {

private final CommentService commentService;
private final ChannelService channelService;

@PostMapping("/add")
public Mono<AddCommentResponse> postComment(@Valid @RequestBody Comment comment, ServerWebExchange serverWebExchange) {
    String userName = serverWebExchange.getAttribute("username");

    return commentService.save(userName, comment);
}
}

运行此命令时,我看到一个错误,指出响应正文为空。在这里:

@RunWith(SpringRunner.class)
@SpringBootTest(properties = {"token-validation-service.url = http://localhost:8080/token-validation-service/", "profanity.similarity = 0.9"})
@AutoConfigureRestDocs(outputDir = "target/generated-snippets")
public class CommentRestControllerDocumentationTest {

@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();

private WebTestClient webTestClient;

@Autowired
private CommentRestController commentRestController;

@MockBean
CommentService commentService;

@MockBean
ChannelService channelService;

@MockBean
ServerWebExchange serverWebExchange;

@MockBean
TokenValidationServiceClient tokenValidationServiceClient;

@MockBean
OperationResult operationResult;

@MockBean
AddCommentResponse addCommentResponse;

private RequestHeadersSnippet requestHeaderSnippet = requestHeaders(headerWithName("X-Auth-Token").description("Authentication Access Token"));

private FieldDescriptor responseReturnCode = fieldWithPath("meta.return_code").description("Operation return code");
private FieldDescriptor responseMessage = fieldWithPath("meta.message").description("Operation message");

private FieldDescriptor idField = fieldWithPath("id").description("id of the comment");
private FieldDescriptor authorField = fieldWithPath("author").description("Author of the comment");
private FieldDescriptor commentField = fieldWithPath("text").description("Comment itself");
private FieldDescriptor channelIdField = fieldWithPath("channelId").description("Channel Id of the comment");
private FieldDescriptor timestampField = fieldWithPath("timestamp").description("Timestamp of the comment");
private FieldDescriptor usernameField = fieldWithPath("username").description("Username of the comment, to check who commented");
private FieldDescriptor isBadField = fieldWithPath("isBad").description("Profanity check for comment");


@Before
public void setUp() {
    webTestClient = WebTestClient.bindToController(commentRestController)
            .configureClient()
            .filter(documentationConfiguration(restDocumentation))
            .build();
}

@Test
@WithMockUser
public void postComment() throws Exception {

    String stubName = "postComment";

    Comment comment = new Comment();
    comment.setId("1");
    comment.setAuthor("orcun");
    comment.setChannelId("123");
    comment.setText("This is a test method");
    comment.setIsBad(false);
    comment.setTimestamp("1479249799770");
    comment.setUsername("5332109939");

    operationResult.setReturnCode(ChatServiceConstants.SUCCESS_CODE);
    operationResult.setMessage(ChatServiceConstants.SUCCESS_MESSAGE);

    addCommentResponse.setOperationResult(operationResult);
    when(serverWebExchange.getAttribute("username")).thenReturn("5332109939");
    String userName = serverWebExchange.getAttribute("username");

    when(commentService.save(userName, comment)).thenReturn(Mono.just(addCommentResponse));

    webTestClient.post().uri("/chat/comment/add")
            .header("X-Auth-Token", "8811-1113")
            .contentType(MediaType.APPLICATION_JSON)
            .accept(MediaType.APPLICATION_JSON)
            .body(BodyInserters.fromObject(comment))
            .exchange()
            .expectStatus().isOk()
            .expectBody()
            .consumeWith(document(stubName,
                    requestFields(idField, authorField, commentField, timestampField,
                            channelIdField, usernameField, isBadField),
                    responseFields(responseReturnCode, responseMessage)));
}
}

当我打开 target / generate-snippets 的路径时,我看到生成了该方法的文档,但response-fields.adoc为空。

我在调试会话中遍历了代码,并且意识到我无法模拟我的 commentService.save() 方法。

任何帮助将不胜感激。 预先感谢。

1 个答案:

答案 0 :(得分:0)

问题在于响应式开发需要与时间无关的应用程序。这就是为什么诸如Twitter或聊天之类的应用程序都使用此功能的原因。在像我这样的大多数情况下,预期的内容甚至无法返回到它所属的位置。

这就是为什么您认为要编写一个单元测试到一个反应式项目要困难一些的原因。

我上面的问题的答案不仅限于此。希望这对人们有所帮助。