2023-02-11-TIL
2023-02-11-TIL
Today I Learned
@SpringBootTest vs @DataJpaTest
@SpringBootTest는 SpringApplication으로 실제와 같은 ApplicationContext를 만들어 테스트한다. 모든 빈과 설정이 올라오므로 통합 테스트에 맞지만 무겁다. @DataJpaTest는 JPA 계층만 잘라 띄우는 슬라이스 테스트다. Spring Boot 문서에 따르면 @Entity 클래스를 스캔하고 Spring Data JPA 저장소를 구성하며, 클래스패스에 내장 DB가 있으면 그것도 구성한다. 일반 @Component 빈은 스캔하지 않고, 각 테스트는 기본적으로 트랜잭션 안에서 실행된 뒤 롤백된다.
저장소 쿼리만 검증할 때는 @DataJpaTest, 여러 계층이 맞물리는 흐름을 검증할 때는 @SpringBootTest를 쓰는 식으로 목적에 따라 고른다.
- https://cobbybb.tistory.com/23
- https://da-nyee.github.io/posts/spring-springboottest-vs-datajpatest/
- https://velog.io/@jwkim/spring-boot-datajpatest-springboottest
- https://stackoverflow.com/questions/59097035/springboottest-vs-webmvctest-datajpatest-service-unit-tests-what-is-the-b
Spring Rest Docs and OAS
Spring REST Docs는 테스트에서 문서 조각(snippet)을 만드는 방식이다. 테스트가 통과해야 문서가 생기고, 응답에 문서화하지 않은 필드나 링크가 있으면 테스트가 실패하므로 문서와 실제 API가 어긋나기 어렵다. 결과물은 Asciidoctor로 엮는 AsciiDoc 문서다. OpenAPI(OAS)는 Swagger 2.0에서 나온 API 명세 형식이고, springdoc 같은 도구가 컨트롤러 애너테이션을 읽어 명세 JSON과 Swagger UI를 만들어 준다. Baeldung 비교 글은 REST Docs가 테스트 주도라 정확하지만 손이 많이 가고, OpenAPI 도구는 빠르지만 프로덕션 코드에 문서용 애너테이션이 섞인다는 점을 대비한다.
두 방식을 섞어, REST Docs 테스트 결과로 OpenAPI 명세를 생성하고 Swagger UI로 보여 주는 조합도 있다. 아래 링크 중 몇 개가 이 조합을 다룬다.
- https://dezang.net/blog/2021/08/22/spring-rest-docs-oas-01
- https://stackoverflow.com/questions/34457729/what-is-the-benefit-of-using-spring-rest-docs-comparing-to-swagger
- https://velog.io/@bread_dd/Spring-Rest-Docs%EC%99%80-Open-Api-Swagger
- https://springframework.guru/should-i-use-spring-rest-docs-or-openapi/
- https://helloworld.kurly.com/blog/spring-rest-docs-guide/
- https://luvstudy.tistory.com/186
- https://dzone.com/articles/spring-rest-docs-versus-springfox-swagger-for-api
- https://catsbi.oopy.io/edcaed06-6df9-4f19-a6f4-05902ad9878d
- https://jwkim96.tistory.com/274
- https://www.baeldung.com/spring-rest-docs-vs-openapi
- https://velog.io/@monkeydugi/Spring-Rest-Docs-%EC%B1%84%ED%83%9D-%EC%9D%B4%EC%9C%A0
- https://piotrminkowski.com/2018/07/19/spring-rest-docs-versus-springfox-swagger-for-api-documentation/
- https://devbksheen.tistory.com/entry/Spring-Docs-Swagger-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0-Spring-Rest-Docs-%EB%B9%84%EA%B5%90
- https://tech.kakaopay.com/post/openapi-documentation/
Java Copy-On-Write
CopyOnWriteArrayList는 add, set 같은 변경 연산마다 내부 배열을 통째로 새로 복사하는 스레드 안전한 리스트다. Javadoc은 이것이 보통은 너무 비싸지만, 순회가 변경보다 압도적으로 많을 때는 다른 방법보다 효율적일 수 있다고 설명한다. 이터레이터는 생성 시점의 배열을 스냅숏으로 참조하므로 순회 중에 다른 스레드가 리스트를 바꿔도 ConcurrentModificationException이 나지 않는다. 대신 그 변경은 이미 만든 이터레이터에 보이지 않는다. 이벤트 리스너 목록처럼 읽기가 대부분인 곳에 맞는다.
- https://www.javamex.com/tutorials/synchronization_concurrency_8_copy_on_write.shtml
- https://dzone.com/articles/java-concurrency-copy-on-write
- https://stackoverflow.com/questions/32691747/how-do-copy-on-write-collections-provide-thread-safety
Java Constant Pool
String은 클래스 내부에 문자열 풀을 두고 같은 내용의 문자열을 하나의 객체로 공유한다. String.intern() Javadoc에 따르면 모든 문자열 리터럴과 문자열 상수 표현식은 자동으로 intern되고, s.intern() == t.intern()은 s.equals(t)일 때만 참이다. 그래서 리터럴끼리는 ==가 우연히 참이 되기도 하지만, new String("abc")로 만든 객체는 풀 밖의 새 객체이므로 문자열 비교는 항상 equals로 해야 한다.
- https://starkying.tistory.com/entry/what-is-java-string-pool
Shallow Copy vs Deep Copy
immutable을 보장해준다면 shallow copy로도 충분하다.
얕은 복사는 객체의 필드 값을 그대로 복사하므로, 필드가 참조 타입이면 원본과 사본이 같은 내부 객체를 가리킨다. 깊은 복사는 참조하는 객체까지 재귀적으로 새로 만든다. 공유된 내부 객체를 아무도 바꿀 수 없다면 공유해도 문제가 생기지 않으니, 불변 객체로 구성된 경우에는 얕은 복사로 충분하다는 것이 위 메모의 뜻이다.
- https://velog.io/@ellyheetov/Shallow-Copy-VS-Deep-Copy
- https://www.geeksforgeeks.org/difference-between-shallow-and-deep-copy-of-a-class/
- https://byjus.com/gate/difference-between-shallow-and-deep-copy-of-a-class/
Java Clone vs Copy Constructor
Object.clone() Javadoc은 이 메서드가 필드를 대입하듯 복사할 뿐 필드의 내용은 복제하지 않는 얕은 복사라고 명시한다. 게다가 Cloneable을 구현해야 하고, CloneNotSupportedException을 처리해야 하며, 반환 타입이 Object라 캐스팅이 필요하다. Baeldung은 복사 생성자가 구현이 쉽고, 캐스팅이 필요 없고, final 필드에도 값을 넣을 수 있다는 점을 장점으로 든다. 그래서 새 코드에서는 clone()보다 복사 생성자나 정적 팩터리를 선호한다.
- https://dzone.com/articles/java-cloning-copy-constructor-vs-cloning
- https://stackoverflow.com/questions/2427883/clone-vs-copy-constructor-which-is-recommended-in-java
- https://www.baeldung.com/java-copy-constructor
- https://ss-o.tistory.com/136
JavaScript Prototype
MDN 설명으로 JavaScript 객체는 모두 프로토타입이라는 내장 속성을 갖고, 프로토타입도 객체이므로 다시 자신의 프로토타입을 가진다. 이렇게 이어진 것이 프로토타입 체인이고, 프로토타입이 null인 객체에서 끝난다. 속성을 찾을 때 객체 자신에 없으면 체인을 따라 올라가며 찾는다. 프로토타입에 접근하는 표준 방법은 Object.getPrototypeOf()이고, 브라우저들이 쓰는 __proto__는 비표준 이름이다.
- https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes
- https://www.nextree.co.kr/p7323/
댓글
아직 댓글이 없습니다