Skip to content

Commit

Permalink
Feature/unit tests (#2)
Browse files Browse the repository at this point in the history
* Unit test HomeController

* Run unit tests in github actions

* Generate jacoco coverage reports

* Unit test main classes

* Update all unit tests
  • Loading branch information
patkub authored Nov 4, 2024
1 parent 52fc297 commit 898ef5a
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 2 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ jobs:
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Build with Gradle
run: ./gradlew build
run: ./gradlew build
- name: Unit Test with Gradle
run: ./gradlew test
12 changes: 12 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
id 'java'
id 'jacoco'

// https://plugins.gradle.org/plugin/org.springframework.boot
id 'org.springframework.boot' version '3.3.5'
Expand Down Expand Up @@ -34,6 +35,8 @@ dependencies {
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: "${springBootVersion}"
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-oauth2-client
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-oauth2-client', version: "${springBootVersion}"
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: "${springBootVersion}"

//
// Thymeleaf
Expand All @@ -48,6 +51,15 @@ dependencies {

test {
useJUnitPlatform()
// report is always generated after tests run
finalizedBy jacocoTestReport
}
jacocoTestReport {
reports {
xml.required = false
csv.required = false
html.outputLocation = layout.buildDirectory.dir('jacocoHtml')
}
}

//
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/example/ProfileController.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
public class ProfileController {

private final Logger log = LoggerFactory.getLogger(this.getClass());
private final static ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
public static ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());

@GetMapping("/profile")
public String profile(Model model, @AuthenticationPrincipal OidcUser oidcUser) {
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/org/example/DemoApplicationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.example;

import org.junit.jupiter.api.Test;

public class DemoApplicationTest {

@Test
public void main() {
// Act
DemoApplication.main(new String[] {});
}

}
51 changes: 51 additions & 0 deletions src/test/java/org/example/HomeControllerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.example;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.ui.Model;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;

@SpringBootTest
class HomeControllerTest {

private HomeController homeController;

@Mock
private Model model;

@Mock
private OidcUser principal;

@BeforeEach
public void beforeEach(){
homeController = new HomeController();
}

@Test
public void testHomeModel(){
// Act
String returnValue = homeController.home(model, principal);

// Assert
verify(model, times(1)).addAttribute(eq("profile"), Mockito.any());
assertEquals("index", returnValue);
}

@Test
public void testHomeModelNullPrincipal(){
// Act
String returnValue = homeController.home(model, null);

// Assert
verify(model, never()).addAttribute(eq("profile"), Mockito.any());
assertEquals("index", returnValue);
}

}
74 changes: 74 additions & 0 deletions src/test/java/org/example/ProfileControllerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.example;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.ui.Model;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;

@SpringBootTest
public class ProfileControllerTest {

private ProfileController profileController;

@Mock
private Model model;

@Mock
private OidcUser oidcUser;

@BeforeEach
public void beforeEach(){
profileController = new ProfileController();
}

@Test
public void testProfileModel() {
// Act
String returnValue = profileController.profile(model, oidcUser);

// Assert
verify(model, times(1)).addAttribute(eq("profile"), Mockito.any());
verify(model, times(1)).addAttribute(eq("profileJson"), Mockito.any());
assertEquals("profile", returnValue);
}

@Test
public void testProfileModel_Exception() throws JsonProcessingException {
// Prepare
// Mock Logger
Logger mockedLogger = Mockito.mock(Logger.class);
ReflectionTestUtils.setField(profileController, "log", mockedLogger);

// Mocked ObjectWriter calls writeValueAsString() and throws JsonProcessingException
ObjectWriter mockedWriter = Mockito.mock(ObjectWriter.class);
when(mockedWriter.writeValueAsString(Mockito.any())).thenThrow(new JsonProcessingException("Error"){});

// Mocked ObjectMapper returns mocked ObjectWriter
ObjectMapper mockedMapper = Mockito.mock(ObjectMapper.class);
when(mockedMapper.writerWithDefaultPrettyPrinter()).thenReturn(mockedWriter);

// Set mocked ObjectMapper on class through reflection
ReflectionTestUtils.setField(profileController, "mapper", mockedMapper);

// Act
String returnValue = profileController.profile(model, oidcUser);

// Assert
verify(model, times(1)).addAttribute(eq("profile"), Mockito.any());
verify(model, times(1)).addAttribute(eq("profileJson"), Mockito.any());
assertEquals("profile", returnValue);
}

}
8 changes: 8 additions & 0 deletions src/test/java/org/example/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.example;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Profile("test")
@Configuration
class SecurityConfig {}

0 comments on commit 898ef5a

Please sign in to comment.