Test Code를 작성하려면 Junit만 사용해도 되지만 Test Code에 대한 가독성이나 편리성을 높여주는 라이브러리들을 활용하면 더 쉽고 편하게 코드를 작성할 수 있다.
Junit에 대한 기본적인 내용은 이전 글 참고!
https://inbeom.tistory.com/entry/JUnit-JUnit%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EA%B8%B0%EB%B3%B8-%EC%A0%95%EB%A6%AC
Junit 기반 테스트 코드를 작성할때 활용할 수 있는 여러 라이브러리가 있지만 가장 많이 사용되는 것은 AssertJ, Unitils, RestAssured 3가지가 있다.
AssertJ
AssertJ는 Java기반의 객체 지향적인 방식으로 테스트 코드를 작성할 수 있게 도와주는 라이브러리이다.
JUnit, TestNG와 같은 테스트 프레임워크와 함께 사용되어 객체의 상태나 동작을 검증하는 데 유용하고, 가독성이 뛰어나며 강력한 검증 기능을 제공하여 테스트 코드 작성을 더 쉽고 효과적으로 만들어준다.
가독성 향상:
AssertJ는 자연어와 유사한 문법을 사용하여 테스트 코드를 작성할 수 있도록 도와준다. 이를 통해 테스트 코드를 읽기 쉽고 이해하기 쉽게 만들어준다
강력한 검증 기능:
AssertJ는 다양한 객체 유형에 대한 강력한 검증 기능을 제공한다. 컬렉션, 맵, 날짜 등 다양한 유형의 객체에 대한 다양한 검증 메서드를 제공한다.
예외 처리:
예외 발생 여부를 검증할 수 있는 기능을 제공한다. 예외 발생 여부와 예외 메시지 등을 검증할 수 있다.
Example >
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
public class PersonTest {
// AssertJ를 사용한 검증
@Test
public void testPerson() {
Person person = new Person("John Doe", 25);
Assertions.assertThat(person)
.isNotNull()
.hasFieldOrPropertyWithValue("name", "John Doe")
.hasFieldOrPropertyWithValue("age", 25);
}
// 예외 검증
@Test
public void testDivideByZero() {
Calculator calculator = new Calculator();
Assertions.assertThatThrownBy(() -> calculator.divide(10, 0))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Cannot divide by zero");
}
}
Unitils
Unitils는 자바 기반의 단위 테스트를 간편하게 작성하고 테스트 환경을 관리하기 위한 라이브러리로 단위테스트에서 자주 발생하는 문제들을 해결하기 위해 개발되었다.
DB 유닛 테스트 지원:
데이터베이스와 관련된 유닛 테스트를 위한 DBUnit과의 통합을 지원한다.
의존성 주입 (DI):
의존성 주입을 사용하여 테스트 대상 객체에 필요한 의존 객체를 쉽게 주입할 수 있다.
모의 객체 (Mock Objects):
EasyMock, Mockito와 같은 모의 객체 라이브러리와의 통합을 지원하여 객체 간 상호작용을 테스트를 할 수 있다.
테스트 데이터 관리:
데이터베이스 초기화 및 정리, 테스트 데이터셋 관리 등을 지원하여 테스트 시 데이터 관리를 용이하게 한다.
Example >
import org.junit.Test;
import org.unitils.UnitilsJUnit4;
import org.unitils.inject.annotation.InjectInto;
import org.unitils.inject.annotation.TestedObject;
import org.unitils.mock.Mock;
public class CalculatorTest extends UnitilsJUnit4 {
@TestedObject
private Calculator calculator; // Calculator 객체를 테스트 대상으로 지정
@InjectInto(property = "calculatorService")
private Mock<CalculatorService> calculatorServiceMock; // CalculatorService의 모의 객체
@Test
public void testAddition() {
calculatorServiceMock.returns(5).add(2, 3);
int result = calculator.performAddition(2, 3);
assertEquals(5, result);
}
}
DataSet 활용
import org.junit.Test;
import org.unitils.UnitilsJUnit4;
import org.unitils.database.annotations.TestDataSource;
import org.unitils.dbunit.annotation.DataSet;
import javax.sql.DataSource;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class UserRepositoryTest extends UnitilsJUnit4 {
@TestedObject
private UserRepository userRepository; // 테스트 대상 객체
@TestDataSource
private DataSource dataSource; // 데이터베이스 연결을 위한 DataSource
@Test
@DataSet("/datasets/users.xml") // 테스트에 사용할 DataSet을 지정
public void testGetAllUsers() {
List<User> userList = userRepository.getAllUsers();
assertEquals(3, userList.size());
}
}
*DataSet 양식 (.xml)
<!-- users.xml -->
<dataset>
<users>
<row userId="1" username="john_doe" age="25" />
<row userId="2" username="jane_smith" age="30" />
<row userId="3" username="bob_jackson" age="28" />
</users>
</dataset>
RestAssured
RestAssured는 RESTful 웹 서비스를 테스트하고 검증하기 위한 자바 기반의 라이브러리이다.
RestA테스트 코드를 작성하고 REST API의 요청과 응답을 효과적으로 다루기 위한 다양한 기능을 제공한다. RESTful 서비스의 자동화된 테스트를 지원하는데 매우 유용하며, 가독성 높은 DSL(Domain Specific Language)을 사용하여 테스트 코드를 작성할 수 있다.
가독성 높은 DSL:
RestAssured는 자연어와 유사한 가독성 높은 DSL을 제공하여 REST API를 테스트하기 쉽게 도와준다.
HTTP 요청 및 응답:
다양한 HTTP 메서드(GET, POST, PUT, DELETE 등)를 사용하여 요청을 보내고, 응답을 검증할 수 있다.
요청 및 응답 스펙 설정:
요청과 응답에 대한 다양한 스펙을 설정하여 테스트의 정확성을 확보할 수 있다.
JSON 및 XML 검증:
JSON 또는 XML 형식의 응답을 쉽게 검증할 수 있다.
쿠키 및 세션 관리:
쿠키와 세션을 효과적으로 다룰 수 있어 인증 및 상태 관리가 용이하다.
헤더 및 파라미터 지원:
요청에 대한 헤더와 파라미터를 설정하여 다양한 시나리오를 테스트할 수 있다.
Example >
import org.testng.annotations.Test;
import static io.restassured.RestAssured.*;
public class RestAssuredExample {
@Test
public void testGetRequest() {
// GET 요청을 보내고 응답을 검증
given()
.when()
.get("https://jsonplaceholder.typicode.com/posts/1")
.then()
.statusCode(200)
.body("userId", equalTo(1));
}
}
AssertJ, Unitils, RestAssured 등의 라이브러리를 활용한 Junit 기반의 Test Case 작성 예시
@Category(ConfigurationAdminController.class)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebAppInitializer.class, AppConfig.class,})
@WebAppConfiguration
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class JunitTest {
private final ObjectMapper objectMapper = new ObjectMapper();
private MockMvc mockMvc;
private static MvcResult result;
private static String methodName = "";
private static MockHttpSession session;
@Autowired
private ConfigurationAdminController controller;
@Autowired
private ConfigurationSystemService service;
@Test
public void junitTest_default() {
System.out.println("TEST SUCCESS!");
}
@Ignore
@Before
public void setUp() throws Exception {
this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
session = new MockHttpSession();
session.setAttribute("userId", "WEEDS01");
}
@After
public void resultPrint() throws Exception {
if(result != null){
System.out.println(methodName+".Result: "+ result.getResponse().getContentAsString());
}
}
/* Unit TEST!
*
* Method - Unitils
* API - RestAssured
* Database(sql) - Unitils
* Integrated - MockMvc
*/
@Parameterized.Parameters
public static SystemParam data() {
return new SystemParam();
}
@Test
@Transactional
public void methodTest() throws Exception {
// given
Admin admin = new System();
AdminListDto dto;
AdminListDto dto2 = new AdminListDto();
dto2.data.list.add(admin);
// when
dto = service.getSystems(data());
// then
assertReflectionEquals(dto2, dto);
}
@Test @Transactional
public void apiTest() {
RestAssured.baseURI = "http://localhost:9090/login";
createSESSION_MAP();
given()
.param("", "")
.when()
.get("/config/admin/business")
.then()
.statusCode(200)
.body(instanceOf(AdminDto.class));
}
@Test @Transactional
public void databaseTest() {}
@Test @Transactional
public void integratedTest() throws Exception {
// given
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("limit", "20");
map.add("offset", "0");
map.add("sys_id", "001");
// when
result = mockMvc.perform(
get("/config/admin/board")
.session(session)
.params(map))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
// then
String responseContent = result.getResponse().getContentAsString();
AdminListDto adminListDto = new ObjectMapper().readValue(responseContent, AdminListDto.class);
assertThat(adminListDto).isNotNull().isInstanceOf(AdminDto.class);
List<Admin> list = adminListDto.data.list;
list.stream().forEach(s -> {
System.out.println("adminListDto.data.list: "+s.getSys_id());
assertThat(s.getSys_id()).isEqualTo("001");
});
assertThat(list).filteredOn(a -> a.getSys_id().contains("001"))
.containsOnly(list.get(0), list.get(1));
assertThat(adminListDto.data.list).hasSize(2);
}
@Ignore(value = "사용하지 않는 테스트")
@Test
public void ignoreTest() {
System.out.println("Testing .. ");
}
}
'📚Framework & Library > JUnit' 카테고리의 다른 글
[Junit] Elasticsearch Unit(Integration) Test Code 작성하기 (0) | 2024.01.23 |
---|---|
[Junit] Test 종류. Test Case (feat. 전자정부 프레임워크) (0) | 2023.11.17 |
[Junit] TypeReference, JsonPath - Json 다루기 (feat. ObjectMapper) (3) | 2023.11.17 |
[JUnit] junit5 간단한 테스트 코드 작성 (0) | 2023.09.10 |
[JUnit] JUnit의 개념과 기본 정리 (0) | 2023.09.10 |