Skip to content

Bash Script file that generates the JUnit Test Cases for Spring Framework based on the tests.json file provided to the script

License

Notifications You must be signed in to change notification settings

DheerajKN/Spring-Test-Generator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spring Test Generator

Open Source Love MIT Licence Bash Shell written-in-shell-script current-version native-support

  • Writing Test Cases for Spring hasn't being more fun than ever.
  • This was created in order to make writing test cases as easy as writing a controller
  • Simple yet powerful Test Case generator

--initialData

The test cases generated by the script requires the presence of initial java files that handles most of the heavylifting so if your using this script for the first time on a project then consider running this script using --initialData flag

./spring-Test-Generator.sh tests.json --initialData
  • --no-auth

    Upon adding this flag after --initialData it will generate functions that doesn't require OAuth2 authentication. So if your project has no authentication at all, then this flag would be beneficial. If your using JWT or other authentication providers then also use this and write custom token generation function inside generated BaseTest file.

    ./spring-Test-Generator.sh tests.json --initialData --no-auth
    

Note

Migration from JUnit 4 to JUnit 5:

From Spring Boot version 2.2.0 or later. Default spring-boot-starter-test dependency calls for JUnit 5. Which has breaking changes from JUnit 4. If your using such version. Just Update the specific section of the code in your BaseTest file from:

@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = SpringApplication.class)
@Ignore
@ActiveProfiles("unittest")
public abstract class BaseTest {

  @Autowired
  private WebApplicationContext wac;
 
  protected MockMvc mockMvc;
  
  @ClassRule
  public static WireMockClassRule wireMockRule = new WireMockClassRule(8089);

  @Rule
  public WireMockClassRule instanceRule = wireMockRule;

	@Autowired
  private FilterChainProxy springSecurityFilterChain;
	
	@Before
  public void setup() {
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
     .addFilter(springSecurityFilterChain).build();
  }

to:

import org.junit.jupiter.api.BeforeEach; 
import org.junit.jupiter.api.Disabled; 
import org.junit.jupiter.api.extension.ExtendWith; 
import org.springframework.boot.test.context.SpringBootTest; 
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 

import org.springframework.security.web.FilterChainProxy; 
import org.springframework.test.context.junit.jupiter.SpringExtension; 
import org.springframework.test.web.servlet.setup.MockMvcBuilders; 
import com.github.tomakehurst.wiremock.WireMockServer; 
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; 

@ExtendWith(SpringExtension.class) 
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) 
@Disabled 
public class BaseTest { 
    @Autowired 
    private WebApplicationContext wac; 

    protected MockMvc mockMvc; 

    protected WireMockServer wireMockRule; 
  
    @Autowired 
    private FilterChainProxy springSecurityFilterChain; 

    @BeforeEach 
    public void setup() { 
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac) 
                .addFilter(springSecurityFilterChain).build(); 
        this.wireMockRule = new WireMockServer(options() 
                .port(8089)); 
    } 

Usage

In Order to use this script without any issues.

At First, we have to install jq Json Processor for the your Environment using:

sudo apt-get install jq

This is for the Debian and Ubuntu Repositories, check out the below link for the rest of the Linux Distributions, MacOS and Windows:

Download jq

When OAuth2 is the authentication engine

Then you have to create the tests.json file or anyother json file present anywhere in this format:

    {
      "package": "com.spring.project", //Package data of the Main file inside Test Directory
      "functions": [
        {
          "fileName": "SimpleController",
          "tests": [
            {
              "functionName": "getDatafromSpringControllerTest",
              "auth": true,
              "authData": "default",
              "type": "GET",
              "endpoint": "/data/2?info=8",
              "result": "HttpStatus.OK",
              "data": ""
            }
          ]
        }
    }

For Post/Put/Delete Requests where we have Data:

    {
      "fileName": "PostDataController",
      "tests": [
        {
          "functionName": "postData",
          "auth": true,
          "authData": "default",
          "type": "Post",
          "endpoint": "/sendData",
          "result": "HttpStatus.OK",
          "data": {
            "1": 1,
            "2": "2",
            "3": true
          }
        }
      ]
    }

For Multipart File Request we have:

    {
      "functionName": "multipartSimpleControllerTest",
      "auth": false,
      "type": "MULTIPART",
      "headers": true,
      "headersData": [
        {
          "key": "token",
          "value": "generateJWTToken()"
        }
      ],
      "fileType": "application/pdf",
      "endpoint": "/data/delete?id=3",
      "result": "HttpStatus.OK"
    }

If you want to use custom email and password apart from the Application Config file authData key is available and make sure that the auth key is set to true by writing your required email<;:semi-colon>password and entering default to authData key would fetch it from ApplicationConfig values.

"auth": true,
"authData": "mailId;password"

If there is an Endpoint that requires headers:

    {
      "fileName": "headerController",
      "tests": [
        {
          "functionName": "headerData",
          "auth": true,
          "authData": "me@mail.com;1234",
          "type": "Get",
          "headers": true,
          "endpoint": "/head",
          "result": "HttpStatus.OK",
          "data": ""
        }
      ]
    }

If in case you have some headers to fill make sure headers key is set to true

    {
      "fileName": "NotificationSettingController",
      "tests": [
        {
          "functionName": "notificationSettingUpdateWithExistingResource",
          "auth": false,
          "type": "POST",
          "headers": true,
          "headersData": [
            {
              "key": "directory",
              "value": "MED"
            },
            {
              "key": "fileName",
              "value": "Medical-2018.pdf"
            }
          ],
          "endpoint": "/notificationSettingUpdate",
          "result": "HttpStatus.OK",
          "data": {
            "1": 21,
            "2": "40%"
          }
        }
      ]
    }

When --no-auth flag is used and authentication is via custom function

In this case the tests.json file is to be generated a bit differently:

    {
      "fileName": "AnotherSimpleControllerWithCustomAuth",
      "tests": [
        {
          "functionName": "putSimpleControllerTest",
          "auth": false,
          "type": "PUT",
          "headers": true,
          "headersData": [
            {
              "key": "token",
              "value": "generateJWTToken(\"email@mail.com\",\"12345678\")"
            },
            {
              "key": "Accept-Language",
              "value": "en"
            },
            {
              "key": "fetchId",
              "value": "2"
            }
          ],
          "endpoint": "/data/put",
          "result": "HttpStatus.OK"
        },
        {
          "functionName": "simpleDeleteControllerTest",
          "type": "DELETE",
          "headers": true,
          "headersData": [
            {
              "key": "token",
              "value": "generateAccessToken()"
            }
          ],
          "endpoint": "/data/put",
          "result": "HttpStatus.OK"
        }
      }
    }

As you can see in Custom Auth scenario the auth json key is to be set false or remove the tag all together and custom Token generation function present in BaseTest file is to be passed in the headersData json key

If your test cases doesn't at all require any authentication then simply:

    {
      "fileName": "ControllerWithNoAuth",
      "tests": [
        {
          "functionName": "freeAccessControllerTest",
          "auth": false,
          "type": "PUT",
          "endpoint": "/data/put",
          "result": "HttpStatus.OK"
        }
    }

As you can see in No Auth scenario the auth json key is either set false or removed all together as simple as that.

If your project already has the required initial Data, then simply run:

./spring-Test-Generator.sh <path to the required json file whose test java files needs to be generated>

As of version 1.1.2 it includes mocking based on com.github.tomakehurst.wiremock

1) All the necessary functions will be be added in BaseTest file no special key is needed while invoking script file

2) All it requires that user add mockData json key to the required functions with some more keys as shown below:

    {
      "functionName": "mockSimpleGetRequestTest",
      "auth": true,
      "type": "GET",
      "mockData": {
        "type": "POST",
        "uri": "/mock/uri?data=3",
        "responseJson": {
          "me": 1
        },
        "response": "HttpStatus.OK"
      },
      "headers": true,
      "headersData": [
        {
          "key": "token",
          "value": "generateJWTToken(\"email@mail.com\",\"12345678\")"
        }
      ],
      "endpoint": "/data/delete?id=3",
      "result": "HttpStatus.OK"
    }

Further Developments

  • if replace key is set to false present at the fileName key then below functions will start to add above the previous functions.
  • saving generated test java files at the given directory location
  • Creating .bat file for Windows so alternatively you can use git bash to execute bash script in Windows
  • result key could be an array or an singular value and subsequent assertions imports required.
  • Testing with JUnit 5 code wiremock changes.

Special Thanks

Special Thanks to stackoverflow user: @vfalcao without whom the main component of this script wouldn't have being developed!!

About

Bash Script file that generates the JUnit Test Cases for Spring Framework based on the tests.json file provided to the script

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages