Generate Unit Test Code from Swagger API for Java REST

Erikson Murrugarra picture Erikson Murrugarra · Sep 21, 2016 · Viewed 11k times · Source

I was trying using Swagger test templates and found this an interesting tool to generate the test files for my controllers, but It seems to just work for NodeJs projects, because there is not a similar tool for the Java platform.

Do somebody knows about how to generate these Test files from my controllers by using a swagger file for spring boot projects?

PD:

I have tried with commercial tools like RepreZen and SwaggerHub but they don't generate the test files for me.

I have also tried by using swagger-generator jar tool to generate those kind of files, but this tool just generate code for Client but no for the Server.

Thx you a lot!.

Answer

naXa picture naXa · Jun 12, 2017

For testing API of Spring-family projects you can use Springfox + AssertJ Swagger libraries. Also you need a YAML file with your API specification. The main idea of this solution is to compare a contract-first Swagger YAML file with a code-first Swagger JSON generated by SpringFox.

Springfox integrates with Spring MVC with support for Swagger 1.2 and Swagger 2.0 spec. Springfox is able to automatically generate JSON API documentation at runtime for API's built with Spring.

Assertj-Swagger is a library which compares a design-first Swagger YAML with an implementation-first Swagger JSON output (e.g. from springfox). assertj-swagger allows to validate that the implementation in compliance with the design specification.

Project setup example

pom.xml

<!-- http://springfox.io -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.6.1</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.6.1</version>
</dependency>

<dependency>
    <groupId>io.github.robwin</groupId>
    <artifactId>assertj-swagger</artifactId>
    <version>0.6.0</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-core</artifactId>
    <version>3.8.0</version>
    <scope>test</scope>
</dependency>

Test code:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class AssertJSwaggerConsumerDrivenTest {

    @LocalServerPort
    int randomPort;

    @Test
    public void validateThatImplementationSatisfiesConsumerSpecification() {
        File designFirstSwagger = new File(AssertJSwaggerConsumerDrivenTest.class.getResource("/swagger.yaml").getFile());
        SwaggerAssertions.assertThat("http://localhost:" + randomPort + "/v2/api-docs")
                .satisfiesContract(designFirstSwagger.getAbsolutePath());
    }    
}

Troubleshooting

  • Exception java.lang.UnsupportedClassVersionError: io/github/robwin/swagger/test/SwaggerAssertions : Unsupported major.minor version 52.0
    Solution: Use JRE 1.8+
  • Exception java.lang.NoSuchMethodError: io.swagger.models.parameters.AbstractSerializableParameter.setMaximum(Ljava/lang/Double;)V
    At the moment of writing AssertJ-Swagger library is incompatible with the latest SpringFox release, so I recommend to use SpringFox v2.6.1.
  • Warning! I find Consumer Driven Contract test too strict for my project, it gives a lot of false errors, e.g. if an actual DTO name differs from a name in the specification.
    I don't know how to fight this issue. All suggestions are welcomed!