{"action":"closed","issue":{"url":"https://api.github.com/repos/spring-cloud/spring-cloud-contract/issues/455","repository_url":"https://api.github.com/repos/spring-cloud/spring-cloud-contract","labels_url":"https://api.github.com/repos/spring-cloud/spring-cloud-contract/issues/455/labels{/name}","comments_url":"https://api.github.com/repos/spring-cloud/spring-cloud-contract/issues/455/comments","events_url":"https://api.github.com/repos/spring-cloud/spring-cloud-contract/issues/455/events","html_url":"https://github.com/spring-cloud/spring-cloud-contract/issues/455","id":273324487,"node_id":"MDU6SXNzdWUyNzMzMjQ0ODc=","number":455,"title":"ContractVerifierTest fails because of missing Header \"Content-Length\"","user":{"login":"HaVonTe1","id":10447166,"node_id":"MDQ6VXNlcjEwNDQ3MTY2","avatar_url":"https://avatars1.githubusercontent.com/u/10447166?v=4","gravatar_id":"","url":"https://api.github.com/users/HaVonTe1","html_url":"https://github.com/HaVonTe1","followers_url":"https://api.github.com/users/HaVonTe1/followers","following_url":"https://api.github.com/users/HaVonTe1/following{/other_user}","gists_url":"https://api.github.com/users/HaVonTe1/gists{/gist_id}","starred_url":"https://api.github.com/users/HaVonTe1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HaVonTe1/subscriptions","organizations_url":"https://api.github.com/users/HaVonTe1/orgs","repos_url":"https://api.github.com/users/HaVonTe1/repos","events_url":"https://api.github.com/users/HaVonTe1/events{/privacy}","received_events_url":"https://api.github.com/users/HaVonTe1/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":6,"created_at":"2017-11-13T06:36:38Z","updated_at":"2018-10-25T10:01:39Z","closed_at":"2018-10-25T10:01:39Z","author_association":"NONE","body":"I generated my Contracts from my Rest Doc Tests like this:\r\n```\r\n        this.mockMvc.perform(post(\"/complain\")\r\n            .content(...)\r\n            .andExpect(status().isAccepted())\r\n            .andDo(\r\n                document(\"complain\",\r\n                    preprocessRequest(prettyPrint()),\r\n                    preprocessResponse(prettyPrint()),\r\n                    SpringCloudContractRestDocs.dslContract()))\r\n            .andDo(\r\n                document(\"complain\",\r\n...\r\n\r\n```\r\nThe generated complain.groovy looks like:\r\n\r\n```\r\nimport org.springframework.cloud.contract.spec.Contract\r\n\r\nContract.make {\r\n    request {\r\n        method 'POST'\r\n        url '/complain'\r\n        body('''\r\n            {\r\n...}\r\n        ''')\r\n        headers {\r\n            header('''Content-Type''', '''application/json''')\r\n            header('''Accept''', '''application/json''')\r\n        }\r\n    }\r\n    response {\r\n        status 202\r\n        body('''\r\n        {\r\n\r\n...\r\n}\r\n        ''')\r\n        headers {\r\n            header('''Content-Type''', '''application/json;charset=UTF-8''')\r\n            header('''Content-Length''', '''417''')\r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nBut than the tests fail with:\r\n```\r\nexpected:<\"447\"> but was:<null>\r\nExpected :\"447\"\r\nActual   :��e\r\n <Click to see difference>\r\n\r\norg.junit.ComparisonFailure: expected:<\"447\"> but was:<null>\r\n\tat sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)\r\n```\r\nIt comes from `ContractVerfierTest`:\r\n```\r\n...\r\n\t\t// then:\r\n\t\t\tassertThat(response.statusCode()).isEqualTo(202);\r\n\t\t\tassertThat(response.header(\"Content-Type\")).isEqualTo(\"application/json;charset=UTF-8\");\r\n\t\t\tassertThat(response.header(\"Content-Length\")).isEqualTo(\"417\");\r\n...\r\n```\r\n\r\nFrom what I understand so far the problem is: my RestController doent respond with the header \"content-lenght\". But this seems to be the default behaviour. \r\nI debugged into `ContractDslSnippet` and found the following methot in Spring Rest Docs `OperationResponseFactory`\r\n\r\n```\r\n\tpublic OperationResponse create(HttpStatus status, HttpHeaders headers,\r\n\t\t\tbyte[] content) {\r\n\t\treturn new StandardOperationResponse(status, augmentHeaders(headers, content),\r\n\t\t\t\tcontent);\r\n\t}\r\n```\r\nCalling `augmentHeaders` will add the \"content-length\" header to the response.\r\n\r\nSo technicaly it is not s-c-contracts fault :)\r\n\r\n**workaround**\r\nI tried something like adding \r\n```\r\n        return ResponseEntity.accepted().contentLength(0).body(response);\r\n```\r\nIn my RestController but this was idiotic.\r\n\r\n**ugly solution so far**\r\nI extended `SpringCloudContractRestDocs` and `ContractDslSnippet` to something like this:\r\n\r\n```\r\npublic class MySpringCloudContractRestDocs {\r\n\r\n    public static Snippet dslContract() {\r\n        return new SlmContractDslSnippet();\r\n    }\r\n\r\n    //just dont ask\r\n    static class MyContractDslSnippet extends ContractDslSnippet {\r\n\r\n        @Override\r\n        public void document(Operation operation) throws IOException {\r\n            OperationResponse operationResponse = operation.getResponse();\r\n            HttpHeaders newHeaders = new HttpHeaders();\r\n            operationResponse.getHeaders().forEach((key, value) -> {\r\n                if (!HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(key)) {\r\n                    value.forEach(v -> newHeaders.add(key, v));\r\n                }\r\n            });\r\n            ReflectionTestUtils.setField(operationResponse, \"headers\", HttpHeaders.readOnlyHttpHeaders(newHeaders));\r\n            super.document(operation);\r\n        }\r\n    }\r\n}\r\n```\r\nIt removes the \"content-lenght\" header befor the groovy file is written.\r\nIt works but it is ugly.\r\n\r\n**Expectation**\r\nThe generated groovy contract file should not contain header/fields which are not covererd by the test."}}
{"actor":{"display_login":"marcingrzejszczak"}}