LogoLogo
diffblue.comFree trial
  • Discover Diffblue Cover
  • Get Started
    • What is Diffblue Cover?
    • Get started
      • Free trial
      • Get started - Cover Plugin
      • Get started - Cover CLI
      • Get started - Cover Pipeline
      • Get started - Cover Reports
    • Specs & Reqs
    • Reference Deployments
    • Licensing
      • Online license activation
      • Offline license activation
      • Diffblue License Manager
    • Update Cover
    • FAQs
    • Diffblue Learning
      • Get started
        • Just the basics
        • Free trial
        • Cover Plugin (IDE)
        • Cover CLI (Command Line)
      • Developer
        • Unit tests (IDE)
        • Unit tests (CLI)
        • Test coverage
      • DevOps
        • GitHub
        • GitLab
        • Other CI
      • Administrator
        • Admin - IntelliJ
        • Admin - CLI
        • Admin - Reports
      • Test coverage
        • Developer
        • Senior developer
        • Cover Reports Administrator
  • EVALUATION & ONBOARDING
    • Proof of Value
    • Jumpstart
      • Prerequisites for onboarding
      • Phase 1: Up and running
        • Module 1: Create your Cover unit test baseline
        • Module 2: Cover Pipeline CI integration
      • Phase 2: Developer productivity
        • Module 3: Getting started using Cover
        • Module 4: Introduction to Cover Reports
      • Phase 3: Advanced topics
        • Module 5: Speed up your test execution
        • Module 6: Getting more from Cover
  • Features
    • Cover Plugin
      • Writing tests
        • Gutter icons
        • Menu options
        • Run configurations
        • Cover Plugin tool window
        • Test Review
        • Test examples
        • Creating partial tests
        • Creating skeleton tests
        • Covering all enum values
        • Test insertion order
        • Diffblue Sandbox
        • Environment Check Cache
      • Project configuration
        • General dependencies
        • Test framework dependencies
      • Cover Plugin settings
        • Test Naming
        • Test Formatting
        • Spring configuration options
        • Method Annotations
        • Test Directory
        • Reset Cover Plugin settings
      • Cover Plugin admin
        • Core Maintenance
        • Cover Plugin toolbar menu
        • Cover Plugin status bar widget
        • Telemetry
        • Memory management
        • Using SonarQube with Cover Plugin
        • Log files
        • Troubleshooting
    • Cover CLI
      • Writing tests
        • Command summary
        • Test examples
        • Creating partial tests
        • Customizing test inputs
        • Customizing test setup
        • Test naming
        • Test formatting
        • Test insertion order
        • Patch files
        • Diffblue Sandbox
        • Operational behaviors
        • Test validation
      • Project configuration
        • Preflight checks
        • General dependencies
        • Test framework dependencies
        • Compiling your project successfully
          • Building a Maven project
          • Building a Gradle project
        • Configuring Cover to work with your project's build system
          • Quick guide
          • Configuration file in detail
          • Getting Started with Ant Projects
          • Default configuration
        • Mocking using Mockito
        • Spring profiles
        • Runtime environment
      • Commands & Arguments
        • Environment configuration for CI
        • Packages, classes, and methods
        • Quoting command line arguments
        • Argument files
      • Cover CLI admin
        • Core Maintenance
        • Telemetry
        • Memory management
        • Using Cover CLI in Eclipse
        • Using SonarQube with Cover CLI
        • Log files
        • Troubleshooting
      • Environment Configuration
    • Cover Pipeline
      • Cover Pipeline for CI
        • Quick Start - General
        • Quick Start - Jenkins
        • Quick Start - Azure Pipelines
        • Quick Start - AWS Codebuild
        • Integrating Diffblue Cover into CI on pull requests
        • Installation - VMs or CI run
      • Cover Pipeline for GitLab
        • Introduction
        • Installation and initial setup
        • GitLab workflow
        • Configuration
        • Troubleshooting
        • Related topics
      • Cover Pipeline for GitHub
        • Introduction
        • Installation and initial setup
        • GitHub workflow
        • Configuration
        • Troubleshooting
        • Related topics
    • Cover Reports
      • Cover Reports Contributor
        • Java project config (JaCoCo)
        • Generate and upload reports bundles
        • Authenticated uploads
      • Cover Reports User
        • Navigation
        • Dashboards
        • Telemetry data
        • Export API
        • Considerations
      • Cover Reports Administrator
        • Install and update Cover Reports
        • Configuration options
        • Database backup
        • SSO with Cover Reports
        • Uninstall Cover Reports
    • Cover Optimize
      • Get started - Cover Optimize
      • Cover Optimize & Gradle
      • Cover Optimize & Maven
      • Patch files
    • Cover Refactor
      • Get started - Cover Refactor
    • Cover Annotations
      • Mocking Annotations
      • Custom Input Annotations
      • Interesting Value Annotations
    • Output Codes
      • E - Environment Codes
      • L - License Codes
      • R - Reason Codes
      • T - Testability Codes
      • V - Validation Codes
      • Working with output codes
        • Working with code E020
        • Working with codes E057 to E065
        • Working with code E085
        • Working with code R005
        • Working with code R006
        • Working with code R008
        • Working with code R011
        • Working with code R012
        • Working with code R013
        • Working with code R026
        • Working with code R031
        • Working with code V003
    • Tutorials
      • How to measure test quality
      • How to improve code coverage
      • How to test a new feature
      • How to find regressions
      • How to use Diffblue Cover in test driven development (TDD)
      • How to write tests for Kotlin projects
      • Examples of tests created by Diffblue Cover
      • Best practices for testing private methods
  • Updates & Upgrades
    • Update Cover
    • Cover Editions
    • What's new
    • Release archive
      • 2025-05-01
      • 2025-04-02
      • 2025-04-01
      • 2025-03-02
      • 2025-03-01
      • 2025-02-02
      • 2025-02-01
      • 2025-01-02
      • 2025-01-01
      • 2024-12-02
      • 2024-12-01
      • 2024-11-02
      • 2024-11-01
      • 2024-10-02
      • 2024-10-01
      • 2024-09-02
      • 2024-09-01
      • 2024-08-02
      • 2024-08-01
      • 2024-07-04
      • 2024-07-03
      • 2024-07-01
      • 2024-06-02
      • 2024-06-01
      • 2024-05-02
      • 2024-05-01
      • 2024-04-02
      • 2024-04-01
      • 2024-03-02
      • 2024-03-01
      • 2024-02-02
      • 2024-02-01
      • 2024-01-02
      • 2024-01-01
      • 2023-12-02
      • 2023-12-01
      • 2023-11-03
      • 2023-11-02
      • 2023-11-01
      • 2023-10-02
      • 2023-10-01
      • 2023-09-02
      • 2023-09-01
      • 2023-08-02
      • 2023-08-01
      • 2023-07-03
      • 2023-07-02
      • 2023-07-01
      • 2023-06-02
      • 2023-06-01
      • 2023-05-02
      • 2023-05-01
      • 2023-04-02
      • 2023-04-01
      • 2023-03-02
      • 2023-03-01
      • 2023-02-02
      • 2023-02-01
      • 2023-01-02
      • 2023-01-01
      • 2022-12-02
      • 2022-12-01
      • 2022-11-02
      • 2022-11-01
      • 2022-10-03
      • 2022-10-02
      • 2022-10-01
      • 2022-09-02
      • 2022-09-01
      • 2022-08-05
      • 2022-08-03
      • 2022-08-02
      • 2022-08-01
      • 2022-07-02
      • 2022-07-01
      • 2022-06-02
      • 2022-06-01
      • 2022-05-02
      • 2022-05-01
      • 2022-04-02
      • 2022-04-01
      • 2022-03-02
      • 2022-03-01
      • 2022-02-02
      • 2022-02-01
      • 2022-01-02
      • 2022-01-01
      • 2021-06-02
      • 2021-02-01
  • Legal
    • Diffblue Legal
      • Diffblue End User License Agreement (EULA)
      • Cover Third Party Notices and/or Licenses
      • Privacy Notice
Powered by GitBook
On this page

Was this helpful?

Export as PDF
  1. Features
  2. Tutorials

How to write tests for Kotlin projects

PreviousHow to use Diffblue Cover in test driven development (TDD)NextExamples of tests created by Diffblue Cover

Last updated 1 year ago

Was this helpful?

This tutorial provides an example of using Diffblue Cover CLI to write Java unit tests for Kotlin projects. We’ll use the to demonstrate practical applications of Diffblue Cover in a real-world project.

First clone the Spring PetClinic Kotlin project from GitHub and then compile the project ready for use with Cover CLI. Finally, run the Diffblue Cover preflight checks to make sure everything is ready for writing tests:

$ dcover create --preflight

Now let’s write unit tests for a Kotlin class within the codebase. We’ll focus on a simplified version of a controller class (PetController), responsible for managing pet information:

@Controller
@RequestMapping("/owners/{ownerId}")
class PetController(val pets: PetRepository, val owners: OwnerRepository) {


   private val VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm"


   @PostMapping("/pets/new")
   fun processCreationForm(owner: Owner, @Valid pet: Pet, result: BindingResult, model: Model): String {
       if (StringUtils.hasLength(pet.name) && pet.isNew && owner.getPet(pet.name!!, true) != null) {
           result.rejectValue("name", "duplicate", "already exists")
       }
       owner.addPet(pet)
       return if (result.hasErrors()) {
           model["pet"] = pet
           VIEWS_PETS_CREATE_OR_UPDATE_FORM
       } else {
           this.pets.save(pet)
           "redirect:/owners/{ownerId}"
       }
   }
}

Run the following Cover CLI command to create unit tests for this HTTP POST controller endpoint - we’ll use the fully-qualified class name of the PetController class on the command line to only create tests for that class.

$ dcover create org.springframework.samples.petclinic.owner.PetController

Running this command will trigger Diffblue Cover to create a set of tests for our entire controller class. As a result, we’ll find a new test class PetControllerDiffblueTest within src/test/java:

@ContextConfiguration(classes = {PetController.class})
@ExtendWith(SpringExtension.class)
class PetControllerDiffblueTest {


   @MockBean
   private OwnerRepository ownerRepository;


   @Autowired
   private PetController petController;


   @MockBean
   private PetRepository petRepository;


   @Test
   void testProcessCreationForm() throws Exception {
       // Arrange
       when(petRepository.findPetTypes()).thenReturn(new ArrayList<>());


       Owner owner = new Owner();
       owner.setAddress("42 Main St");
       owner.setCity("Oxford");
       owner.setFirstName("Jane");
       owner.setId(1);
       owner.setLastName("Doe");
       owner.setPets(new HashSet<>());
       owner.setTelephone("6625550144");
       when(ownerRepository.findById(anyInt())).thenReturn(owner);
       MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/owners/{ownerId}/pets/new", 1);


       // Act and Assert
       MockMvcBuilders.standaloneSetup(petController)
           .build()
           .perform(requestBuilder)
           .andExpect(MockMvcResultMatchers.status().isOk())
           .andExpect(MockMvcResultMatchers.model().size(3))
           .andExpect(MockMvcResultMatchers.model().attributeExists("owner", "pet", "types"))
           .andExpect(MockMvcResultMatchers.view().name("pets/createOrUpdatePetForm"))
           .andExpect(MockMvcResultMatchers.forwardedUrl("pets/createOrUpdatePetForm"));
   }


   // more tests for this controller endpoint
}

This auto-created test class contains test methods for all controller endpoints of the PetController class. Cover automatically writes a set of unit tests for each controller endpoint to cover various scenarios. We can immediately run the tests as Diffblue Cover ensures that the tests compile and execute successfully.

As you can see, the test class created by Diffblue Cover is a Java test class. Currently, Diffblue Cover only supports Java test classes as an output format. However, there’s a simple way to automatically convert this test to Kotlin, if needed - see below.

Convert Java unit tests to Kotlin

Converting Java unit tests into Kotlin using IntelliJ’s conversion feature facilitates a smoother transition for companies migrating from Java to Kotlin. This capability not only streamlines the adaptation process by automating the conversion of existing test suites, but also ensures that legacy tests remain functional and relevant in the new Kotlin codebase.

Such a feature is particularly valuable for maintaining test coverage and quality assurance during the migration, allowing teams to leverage Kotlin’s concise syntax and modern features without losing the robustness of their Java-based tests.

To convert Java unit tests into Kotlin in IntelliJ IDEA, open the Java test file in IntelliJ and select Code > Convert Java File to Kotlin File from the menu.

For our auto-created Java test class PetControllerDiffblueTest, we get the following - a quick, simple, and accurate conversion:

 /**
* Method under test:
* [PetController.processCreationForm]
*/
@Test
@Throws(Exception::class)
fun testProcessCreationForm3() {
   // Arrange
   Mockito.`when`(petRepository!!.findPetTypes()).thenReturn(ArrayList())


   val owner = Owner()
   owner.address = "42 Main St"
   owner.city = "Oxford"
   owner.firstName = "Jane"
   owner.id = 1
   owner.lastName = "Doe"
   owner.pets = HashSet()
   owner.telephone = "6625550144"
   Mockito.`when`(ownerRepository!!.findById(ArgumentMatchers.anyInt())).thenReturn(owner)
   val requestBuilder = MockMvcRequestBuilders.post("/owners/{ownerId}/pets/new", 1)
   requestBuilder.contentType("text/plain")


   // Act and Assert
   MockMvcBuilders.standaloneSetup(petController)
           .build()
           .perform(requestBuilder)
           .andExpect(MockMvcResultMatchers.status().isOk())
           .andExpect(MockMvcResultMatchers.model().size(3))
           .andExpect(MockMvcResultMatchers.model().attributeExists("owner", "pet", "types"))
           .andExpect(MockMvcResultMatchers.view().name("pets/createOrUpdatePetForm"))
           .andExpect(MockMvcResultMatchers.forwardedUrl("pets/createOrUpdatePetForm"))
}
Spring PetClinic Kotlin codebase