diff --git a/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDriverCarDto.java b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDriverCarDto.java
index 0e635504e632573c917679554c2b16ccd4e31935..163da951a77d1f16d721744234e0fa2c666a821a 100644
--- a/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDriverCarDto.java
+++ b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDriverCarDto.java
@@ -2,14 +2,18 @@ package cz.muni.pa165.common_library.dtos;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import jakarta.validation.constraints.NotNull;
+import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 /**
  * Dto fro DriverCar entity.
  */
 @Data
 @Builder
+@NoArgsConstructor
+@AllArgsConstructor
 public class RaceDriverCarDto {
 
   @Schema(description = "driver id", example = "1")
diff --git a/race/src/main/java/cz/muni/pa165/race/service/DbGetter.java b/race/src/main/java/cz/muni/pa165/race/service/DbGetter.java
new file mode 100644
index 0000000000000000000000000000000000000000..e8f0b5bc40e854f00e2c2e60d1b91312d6cb9913
--- /dev/null
+++ b/race/src/main/java/cz/muni/pa165/race/service/DbGetter.java
@@ -0,0 +1,41 @@
+package cz.muni.pa165.race.service;
+
+import cz.muni.pa165.common_library.dtos.CarResponseDto;
+import cz.muni.pa165.common_library.dtos.DriverDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * Getter for driver and car from appropriate modules.
+ */
+@Component
+public class DbGetter {
+
+  @Autowired
+  RestTemplate client;
+
+  /**
+   * Calls driver module for a driver given by id.
+   *
+   * @param driverId id of a driver.
+   * @return driverDto.
+   */
+  public DriverDto getDriver(Long driverId) {
+    var response =
+        client.getForEntity("http://localhost:8083/driver/get/id=" + driverId, DriverDto.class);
+    return response.getBody();
+  }
+
+  /**
+   * Calls car module for a car given by id.
+   *
+   * @param carId id of a car.
+   * @return carDto.
+   */
+  public CarResponseDto getCar(Long carId) {
+    var response =
+        client.getForEntity("http://localhost:8082/car/?carId=" + carId, CarResponseDto.class);
+    return response.getBody();
+  }
+}
diff --git a/race/src/main/java/cz/muni/pa165/race/service/RaceService.java b/race/src/main/java/cz/muni/pa165/race/service/RaceService.java
index ad0ff086584e5b069e37b0b1a937903042b8bc0f..2165c89ad614639b68514efa34ffa4938a5e495a 100644
--- a/race/src/main/java/cz/muni/pa165/race/service/RaceService.java
+++ b/race/src/main/java/cz/muni/pa165/race/service/RaceService.java
@@ -33,7 +33,7 @@ public class RaceService implements RaceServiceI {
   RaceRepository raceRepository;
 
   @Autowired
-  RestTemplate client;
+  DbGetter dbGetter;
 
   RaceService(RaceRepository raceRepository) {
     this.raceRepository = raceRepository;
@@ -70,12 +70,12 @@ public class RaceService implements RaceServiceI {
     var race = raceRepository.findById(raceId)
         .orElseThrow(() -> new DatabaseException("Race not found"));
 
-    var driver = getDriver(driverId);
+    var driver = dbGetter.getDriver(driverId);
     if (race.getDriver2() != null && Objects.equals(race.getDriver2().getDriverId(), driverId)) {
       throw new BadRequestException("Driver already assigned to the race as driver two");
     }
 
-    var car = getCar(carId);
+    var car = dbGetter.getCar(carId);
     if (race.getDriver2() != null && Objects.equals(race.getDriver2().getCarId(), carId)) {
       throw new BadRequestException("Car is already assigned to the race for driver two");
     }
@@ -92,11 +92,11 @@ public class RaceService implements RaceServiceI {
     var race = raceRepository.findById(raceId)
         .orElseThrow(() -> new DatabaseException("Race not found"));
 
-    var driver = getDriver(driverId);
+    var driver = dbGetter.getDriver(driverId);
     if (race.getDriver1() != null && Objects.equals(race.getDriver1().getDriverId(), driverId)) {
       throw new BadRequestException("Driver already assigned to the race as driver one");
     }
-    var car = getCar(carId);
+    var car = dbGetter.getCar(carId);
     if (race.getDriver1() != null && Objects.equals(race.getDriver1().getCarId(), carId)) {
       throw new BadRequestException("Car is already assigned to the race for driver two");
     }
@@ -263,15 +263,5 @@ public class RaceService implements RaceServiceI {
     return raceDto;
   }
 
-  private DriverDto getDriver(Long driverId) {
-    var response =
-        client.getForEntity("http://localhost:8083/driver/get/id=" + driverId, DriverDto.class);
-    return response.getBody();
-  }
 
-  private CarResponseDto getCar(Long carId) {
-    var response =
-        client.getForEntity("http://localhost:8082/car/?carId=" + carId, CarResponseDto.class);
-    return response.getBody();
-  }
 }
diff --git a/race/src/test/java/cz/muni/pa165/race/rest/CarManagerControllerItTest.java b/race/src/test/java/cz/muni/pa165/race/rest/CarManagerControllerItTest.java
deleted file mode 100644
index e82f209188304e317bf15cc272844096c84690fc..0000000000000000000000000000000000000000
--- a/race/src/test/java/cz/muni/pa165/race/rest/CarManagerControllerItTest.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package cz.muni.pa165.race.rest;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.web.servlet.MockMvc;
-
-@SpringBootTest
-@AutoConfigureMockMvc
-class CarManagerControllerItTest {
-
-  @Autowired
-  private MockMvc mockMvc;
-
-  @Autowired
-  private ObjectMapper objectMapper;
-
-
-}
diff --git a/race/src/test/java/cz/muni/pa165/race/rest/RaceControllerTest.java b/race/src/test/java/cz/muni/pa165/race/rest/RaceControllerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..39665d916965a9603379237cae4c234eae5b1b50
--- /dev/null
+++ b/race/src/test/java/cz/muni/pa165/race/rest/RaceControllerTest.java
@@ -0,0 +1,154 @@
+package cz.muni.pa165.race.rest;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.BDDMockito.given;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import cz.muni.pa165.common_library.dtos.CarResponseDto;
+import cz.muni.pa165.common_library.dtos.DriverDto;
+import cz.muni.pa165.race.data.model.Race;
+import cz.muni.pa165.race.data.repository.RaceRepository;
+import cz.muni.pa165.race.service.DbGetter;
+import java.util.List;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class RaceControllerTest {
+
+  private String bodyContent = """
+            {
+              "id": 1,
+              "raceInfo": {
+                "location": "MONACO",
+                "name": "Monaco Grand Prix 2023",
+                "prizePool": 30000000
+              }
+            }
+        """;
+  private String expectedMessagePost = "{\"id\":1,\"raceInfo\":{\"location\":\"MONACO\","
+      + "\"name\":\"Monaco Grand Prix 2023\",\"prizePool\":30000000},\"driverOne\""
+      + ":{\"driverId\":1,\"carId\":1,\"position\":null},\"driverTwo\":{\"driverId\""
+      + ":2,\"carId\":2,\"position\":null}}";
+  private String expectedMessageAssignTwo = "{\"id\":1,\"raceInfo\":{\"location\":"
+      + "\"MONACO\",\"name\":\"Monaco Grand Prix 2023\",\"prizePool\":30000000},"
+      + "\"driverOne\":{\"driverId\":1,\"carId\":1,\"position\":null},\"driverTwo\""
+      + ":{\"driverId\":1,\"carId\":1,\"position\":null}}";
+  private String expectedMessageGet = "{\"id\":1,\"raceInfo\":{\"location\":\"MONACO\""
+      + ",\"name\":\"Monaco Grand Prix 2023\",\"prizePool\":30000000},\"driverOne\""
+      + ":{\"driverId\":1,\"carId\":1,\"position\":null},\"driverTwo\":{\"driverId\""
+      + ":2,\"carId\":2,\"position\":null}}";
+  private String expectedMessageGetAll = "[{\"id\":1,\"raceInfo\":{\"location\""
+      + ":\"MONACO\",\"name\":\"Monaco Grand Prix 2023\",\"prizePool\":30000000},\""
+      + "driverOne\":{\"driverId\":1,\"carId\":1,\"position\":null},\"driverTwo\":{\""
+      + "driverId\":2,\"carId\":2,\"position\":null}}]";
+
+  @Autowired
+  private MockMvc mockMvc;
+
+  @MockBean
+  private RaceRepository raceRepository;
+
+  @MockBean
+  private DbGetter dbGetter;
+
+  @BeforeEach
+  void setup() {
+    Race raceDao = RaceTestUtil.getDaoRace();
+    given(raceRepository.save(any(Race.class))).willReturn(
+        raceDao);
+    given(raceRepository.findById(anyLong())).willReturn(
+        Optional.of(raceDao));
+    given(raceRepository.findAll()).willReturn(List.of(raceDao));
+    CarResponseDto carDao = RaceTestUtil.getCarDao();
+    given(dbGetter.getCar(anyLong())).willReturn(carDao);
+    DriverDto driverDto = RaceTestUtil.getDriverDao();
+    given(dbGetter.getDriver(anyLong())).willReturn(driverDto);
+  }
+
+
+  @Test
+  void createRace() throws Exception {
+    var request = post("/race/")
+        .content(bodyContent)
+        .contentType(MediaType.APPLICATION_JSON_VALUE);
+    this.mockMvc.perform(request)
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(content().string(expectedMessagePost));
+  }
+
+  @Test
+  void deleteRace() throws Exception {
+    String expectedMessage = "Race with id: 1was succesfully deleted";
+    var requestDelete = delete("/race/")
+        .param("raceId", "1")
+        .contentType(MediaType.APPLICATION_JSON_VALUE);
+    this.mockMvc.perform(requestDelete)
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(content().string(expectedMessage));
+  }
+
+  @Test
+  void getExistingRace() throws Exception {
+    var requestGet = get("/race/id")
+        .param("raceId", "1")
+        .contentType(MediaType.APPLICATION_JSON_VALUE);
+    this.mockMvc.perform(requestGet)
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(content().string(expectedMessageGet));
+  }
+
+  @Test
+  void getAllRaces() throws Exception {
+    var requestGet = get("/race/");
+    this.mockMvc.perform(requestGet)
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(content().string(expectedMessageGetAll));
+  }
+
+  @Test
+  void assignDriverOne() throws Exception {
+    var requestAssign = patch("/race/assignDriverOne")
+        .param("driverOneId", "1")
+        .param("raceId", "1")
+        .param("carId", "1")
+        .contentType(MediaType.APPLICATION_JSON_VALUE);
+    this.mockMvc.perform(requestAssign)
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(content().string(expectedMessagePost));
+  }
+
+  @Test
+  void assignDriverTwo() throws Exception {
+    var requestAssign = patch("/race/assignDriverTwo")
+        .param("driverTwoId", "2")
+        .param("raceId", "2")
+        .param("carId", "2")
+        .contentType(MediaType.APPLICATION_JSON_VALUE);
+    this.mockMvc.perform(requestAssign)
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(content().string(expectedMessageAssignTwo));
+  }
+
+}
diff --git a/race/src/test/java/cz/muni/pa165/race/rest/RaceTestUtil.java b/race/src/test/java/cz/muni/pa165/race/rest/RaceTestUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..164179e3da60e8707866bd623ab3b462a4f1e49d
--- /dev/null
+++ b/race/src/test/java/cz/muni/pa165/race/rest/RaceTestUtil.java
@@ -0,0 +1,47 @@
+package cz.muni.pa165.race.rest;
+
+import cz.muni.pa165.common_library.dtos.CarResponseDto;
+import cz.muni.pa165.common_library.dtos.DriverDto;
+import cz.muni.pa165.common_library.dtos.Location;
+import cz.muni.pa165.race.data.model.Race;
+
+/**
+ * Util functions for race tests.
+ */
+public class RaceTestUtil {
+  /**
+   * Returns a created race.
+   *
+   * @return a race.
+   */
+  public static Race getDaoRace() {
+    return Race.builder()
+        .id(1L)
+        .raceInfo(Race.RaceInfo.builder()
+            .id(1L)
+            .location(Location.MONACO)
+            .name("Monaco Grand Prix 2023")
+            .prizePool(30000000L).build())
+        .driver1(Race.RaceDriverinfo.builder()
+            .id(1L)
+            .driverId(1L)
+            .carId(1L)
+            .finalPosition(1)
+            .build())
+        .driver2(Race.RaceDriverinfo.builder()
+            .id(2L)
+            .driverId(2L)
+            .carId(2L)
+            .finalPosition(2)
+            .build())
+        .build();
+  }
+
+  public static CarResponseDto getCarDao() {
+    return new CarResponseDto(1L, null, null, 1L);
+  }
+
+  public static DriverDto getDriverDao() {
+    return new DriverDto(1L, "Name", "Surname");
+  }
+}
diff --git a/race/src/test/java/cz/muni/pa165/race/rest/SeasonControllerTest.java b/race/src/test/java/cz/muni/pa165/race/rest/SeasonControllerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..bc1ce050604d6f00faae2409ba25fae8be4d9b0b
--- /dev/null
+++ b/race/src/test/java/cz/muni/pa165/race/rest/SeasonControllerTest.java
@@ -0,0 +1,124 @@
+package cz.muni.pa165.race.rest;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.BDDMockito.given;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import cz.muni.pa165.race.data.model.Race;
+import cz.muni.pa165.race.data.model.Season;
+import cz.muni.pa165.race.data.repository.RaceRepository;
+import cz.muni.pa165.race.data.repository.SeasonRepository;
+import java.util.List;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+/**
+ * Tests for season controller.
+ */
+@SpringBootTest
+@AutoConfigureMockMvc
+public class SeasonControllerTest {
+  private String bodyContent = """
+          {
+          "id": 1,
+          "year": 2020,
+          "races": []
+        }
+      """;
+  private String expectedMessagePost = "{\"id\":1,\"year\":2023,\"races\":[]}";
+  private String expectedMessageDelete = "Season with id: 1was succesfully deleted";
+  private String expectedMessageGet = "{\"id\":1,\"year\":2023,\"races\":[]}";
+  private String expectedMessageGetAll = "[{\"id\":1,\"year\":2023,\"races\":[]}]";
+  private String expectedMessageAddRace = "{\"id\":1,\"year\":2023,\"races\":[{\""
+      + "id\":1,\"name\":\"Monaco Grand Prix 2023\"}]}";
+
+  @Autowired
+  private MockMvc mockMvc;
+
+  @MockBean
+  private SeasonRepository seasonRepository;
+
+  @MockBean
+  private RaceRepository raceRepository;
+
+  @BeforeEach
+  void setup() {
+    Season seasonDao = SeasonTestUtil.getDaoSeason();
+    Race raceDao = RaceTestUtil.getDaoRace();
+    given(seasonRepository.save(any(Season.class))).willReturn(
+        seasonDao);
+    given(seasonRepository.findById(anyLong())).willReturn(
+        Optional.of(seasonDao));
+    given(seasonRepository.findAll()).willReturn(List.of(seasonDao));
+    given(raceRepository.findById(anyLong())).willReturn(
+        Optional.of(raceDao));
+  }
+
+
+  @Test
+  void createSeason() throws Exception {
+    var request = post("/season/")
+        .content(bodyContent)
+        .contentType(MediaType.APPLICATION_JSON_VALUE);
+    this.mockMvc.perform(request)
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(content().string(expectedMessagePost));
+  }
+
+  @Test
+  void deleteRace() throws Exception {
+    var requestDelete = delete("/season/")
+        .param("seasonId", "1")
+        .contentType(MediaType.APPLICATION_JSON_VALUE);
+    this.mockMvc.perform(requestDelete)
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(content().string(expectedMessageDelete));
+  }
+
+  @Test
+  void getExistingRace() throws Exception {
+    var requestGet = get("/season/id")
+        .param("seasonId", "1")
+        .contentType(MediaType.APPLICATION_JSON_VALUE);
+    this.mockMvc.perform(requestGet)
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(content().string(expectedMessageGet));
+  }
+
+  @Test
+  void getAllRaces() throws Exception {
+    var requestGet = get("/season/");
+    this.mockMvc.perform(requestGet)
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(content().string(expectedMessageGetAll));
+  }
+
+  @Test
+  void addRace() throws Exception {
+    var requestPatch = patch("/season/addRace")
+        .param("seasonId", "1")
+        .param("raceId", "1");
+    this.mockMvc.perform(requestPatch)
+        .andDo(print())
+        .andExpect(status().isOk())
+        .andExpect(content().string(expectedMessageAddRace));
+  }
+}
diff --git a/race/src/test/java/cz/muni/pa165/race/rest/SeasonTestUtil.java b/race/src/test/java/cz/muni/pa165/race/rest/SeasonTestUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c73931528a779d6004cb7db18fed7b641150cee
--- /dev/null
+++ b/race/src/test/java/cz/muni/pa165/race/rest/SeasonTestUtil.java
@@ -0,0 +1,22 @@
+package cz.muni.pa165.race.rest;
+
+import cz.muni.pa165.race.data.model.Season;
+import java.util.ArrayList;
+
+/**
+ * Utils for season tests.
+ */
+public class SeasonTestUtil {
+  /**
+   * Returns a created Season.
+   *
+   * @return a season.
+   */
+  public static Season getDaoSeason() {
+    return Season.builder()
+        .id(1L)
+        .seasonYear(2023)
+        .races(new ArrayList<>())
+        .build();
+  }
+}