# mock
테스트: 행위 검증과 상태 검증
테스트: 행위 검증과 상태 검증 > 해당 내용은 WifiObserver라는 와이파이 공유기의 접속 목록을 크롤링 하여 해당 정보를 활용하는 프로젝트를 수행하며 공부한 내용입니다. > > 깃 허브 바로가기 테스트 테스트를 통해 검증할 수 있는 것은 크게 아래 2가지라고 할 수 있다. 상태 검증 행위 검증 상태검증 우선 상태 검증이라는 것은 적절한 "인풋"을 제공하여 원하는 "아웃풋"이 나오는지 확인하는 검증이라 할 수 있다. 만약 위의 add라는 함수를 상태 검증하려면 어떻게 해야 할까? 1과 2라는 적절한 인풋을 제공하고 그 아웃풋이 3이 나오는지 확인하면 될 것이다. 이렇게 상태 검증 테스트의 경우 내가 만든 코드가 내가 원하는 대로 동작하는지 테스트하는 것이다. 행위검증 그럼, 행위 검증

[MockTest] Mocking하여 Controller Test
Domain model 프로젝트 진행 중 Toss payments API를 활용하여 카드 결제 시스템을 구현 중이었다. 토스 외부 API 서버를 사용하는 통합테스트가 아닌 단위 테스트를 하려고 했다. 그 이유는 다음과 같다. >1. 독립성: 외부 서버를 Mocking하면 테스트 시에 외부 서버의 상태나 가용성에 영향을 받지 않는다. 이는 테스트의 안정성과 신뢰성을 높여준다. >2. 빠른 테스트 속도: 외부 서버를 호출하는 테스트는 네트워크 지연으로 인해 느려질 수 있다. 하지만 Mocking을 통해 실제 네트워크 호출을 회피하면 테스트가 더 빠르게 실행된다. >3. 테스트 제어: Mocking을 통해 응답을 조작할 수 있으므로 다양한 시나리오를 시뮬레이션하여 테스트를 보다 철저하게 수행할 수 있
Java TDD - 1
강의를 들으면서 정리한 TDD 1. TDD 실패 이유 너무 맘에 와닿았다. Service로직 짜는데는 10분이면 되는데 그걸 테스트 할려고 그에 배에 대한 시간이 들어가고. 뿐만 아니라 DB, File 등 여러가지 복잡한 테스트들은 테스트 짠다고 하루 이틀 쓴적도 많이 있다. 테스트를 하니까 오히려 속도가 느려진다. 진짜 내가 겪는 상황이라 공감이 갔다. 문제점 코드에 테스트를 넣는다고 무조건 TDD가 아니다. 테스트의 목적은 1. 회귀버그 방지와 2. 유연한 설계를 할 수 있게 한다. 이중 유연한 설계가 중요하다고 한다. 커버리지에 집착하면 안된다. - 테스트가 필요 없는 부분은 빼버려야한다... 마음이 아프다. > 결론은 TDD 이전에 테스트가 가능한 구조로 코드가 변경되어야 한다는 것이다 나는 뭔가 지금까지 테스트를 위한 테스트만 짜고 있었던것 같다. 일단 이제부터 테스트를 필요한 부분만 짜야겠다 2. 테스트란 시스템이 잘 돌아가는지 검정 1
테스트: 행위 검증과 상태 검증
테스트: 행위 검증과 상태 검증 깃허브 바로가기 테스트를 통해 검증할 수 있는 것은 크게 아래 2가지라고 할 수 있다. 상태 검증 행위 검증 우선 상태 검증이라는 것은 적절한 "인풋"을 제공하여 원하는 "아웃풋"이 나오는지 확인하는 검증이라 할 수 있다. 만약 위의 add라는 함수를 상태 검증하려면 어떻게 해야 할까? 1과 2라는 적절한 인풋을 제공하고 그 아웃풋이 3이 나오는지 확인하면 될 것이다. 이렇게 상태 검증 테스트의 경우 내가 만든 코드가 내가 원하는 대로 동작하는지 테스트하는 것이다. 그럼, 행위 검증이란 무엇을 검증하는 것일까? 말 그대로 그대로 테스트할 객체의 메서드가 어떤 행위를 하는지 검증하는 것이다. 이 행위라는 말이 애매할 수 있으리라 생각한다. 정확하지는 않을 수 있지만 이번 프로젝트에서
[Test] Mock, Mockito, MockMVC
Mock Mock이란 모조품이라는 뜻으로, Mock 객체란 실제의 모듈을 흉내내는 가짜 모듈을 작성하여 테스트의 효용성을 높이는 데 사용하는 객체. Mockito mock을 쉽게 만들고 mock의 행동을 정하는 stubbing이나 정상적으로 작동하는지에 대한 verify 등 다양한 기능을 제공해주는 프레임워크. Mock 객체를 직접 구현하지 않아도 됨. Mockito 설정 의존성 설정 테스트 클래스 위에 @ExtendWith(MockitoExtension.class) 붙여야 함. MockMVC 브라우저에서 요청과 응답을 의마하는 객체로서 Controller 테스트를 용이하게 해주는 라이브러리. MockMVC 메서드 perform() : 요청을 전송하는 역할. 결과로 ResultActions 객체를 받으며, ResultAction

Spring static method 테스트 하는법
먼저 static method를 모킹하는 방법에 대해 소개하고 wrapper로 활용해 psa를 만족하는 방법을 소개하겠다. 1. static method 모킹 Mockito로 static method를 모킹할려고 하면 해당 static method를 모킹 할 수 없는거에 당황을 하게 된다. 이럴때 테스트를 위해서는 기본적으로 두가지 방법이 있다. 우선 테스트 대상의 코드 중 static method를 호출하는 부분은 다음과 같다. >static method -> BearerTokenResolver.resolve(request) 1.1. static method의 파라미터를 모킹 직접 static method를 모킹하는게 아니라 static method의 인수값을 모킹해 원하는 결
@mock @spy
@Mock @Spy 어떤 상황에 쓰면 더 효과적일까? @Mock : 내가 신경을 전혀쓰고 싶지 않고, 사용하고자 하는 method만 내가 재정의 해줄 때 @Spy : new ... 객체와 비슷, 하지만 mock처럼 다시 재정의가 가능하다. spy안에 mock의 개념이 있다. 거의 mock을 많이 사용한다.
[Jest] 테스트에 필요한 Mock 데이터를 JSON 파일로 만들어보자
0. Overview Spec 1. Preface 당연한 이야기지만 어떤 기능을 개발할 때, 테스트는 필수적입니다. 단위 테스트, 통합 테스트 등 테스트의 종류도 많고, 각 테스트를 올바르게 실행하기 위해서는 다양한 테스트 케이스도 필요합니다. 그리고 이 다양한 테스트 케이스를 위해서는 "데이터"가 필요합니다. 데이터는 직접 개발 환경 DB 에 만들어 넣을 수도 있고, 임의의 Mock 데이터를 만들수도 있습니다. 실제 환경과 비슷한 테스트를 위해서는 당연히 실제 DB 에 데이터를 만들어서 넣는게 좋겠지만, 테스트 도중에 데이터의 타입이나 구성이 변경되면 모든 테스트 데이터를 다시 만들어 넣거나, 모두 수정해야하는 번거로운 작업이 생길 수도 있습니다. 경우에 따라서는 좀더 간단한 Mock 데이터를 이용해 테스트하고 데이터의 변경이나 수정에 빠르게 대응하다가 최종적인 테스트에는 직접 DB 에 데이터를 만들어 넣어서 테스트를 하는 것이 더 편할 수도 있습니다

[ ARVZ ] Mock에 대해 알아보자.
내용 출처 - 우아한테크 [10분 테코톡] 더즈, 티키의 Classic TDD VS Mockist TDD [ Test double이란? ] > 테스트를 진행하기 어려운 경우 이를 대신해 테스트를 진행할 수 있도록 만들어주는 객체를 말한다. >> Stunt double에서 따온 말이다. 영화나 드라마에서, 액션 또는 위험한 장면을 촬영할 때 스턴트맨을 고용해 가짜 배우로 촬영하는 것처럼 테스트도 가짜 객체로 테스트 하겠다는 뜻. Test double의 종류 1.Dummy > - 가장 기본적인 테스트 더블. 인스턴스화 된 객체가 필요하지만 기능은 필요하지 않은 경우에 사용. Dummy 객체의 메서드가 호출되었을 때 정상 동작은 보장하지 않음. 객체는 전달되지만 사용되지 않는 객체. 2.Fake > - 복잡한 로직이나 객체 내부에서 필요로 하는 다른 외부 객체들의
[Jest] 함수 Mocking: spyOn().mockImplementation()
0. Overview Examples Spec 1. Preface 이번에 참가한 프로젝트에서는 "아직 개발되지 않은 기능"을 이용해서 개발해야하는 경우가 상당히 많았습니다. 예를 들면, "회원의 쿠폰 데이터를 불러오고 싶은데 회원 정보를 불러오는 기능이 아직 개발되지 않은 상황"이라는 겁니다. 이러한 경우가 있을 때마다 개발되지 않은 부분의 함수를 mocking 하여 테스트 코드를 작성했었는데, 이럴 때 사용하는 것이 jest 의 spyOn().mockImplementation() 함수입니다. 이번 포스트에서는 자주 사용하고 있는 jest.spyOn().mockImplementation() 메소드에 대해 간략히 정리하고자 합니다. 2. Problem code1 은 회원의 ID 를 파라미터로 받아 해당 회원의 쿠폰 리스트를 불러오는 코드입니다. 여기서 1) 해당 유저가 실제 존재하는 유저인지 확인한다. 부분이
Graph, Testing
최소 신장 트리 (MST) 그래프를 통해서 만들수 있는 모든 신장트리 중 해당 트리를 이루는 간선들의 합이 최소인 신장트리를 말한다. Kruskal Kruskal 알고리즘은 그래프 간선들을 오름차순을 정렬하여 가장 낮은 가중치의 간선부터 차례로 추가하는 방법이다. 동작 방식 그래프의 간선들을 가중치(비용)의 오름차순으로 정렬한다. 정렬된 간선 리스트에서 가장 작은 가중치를 가진 간선을 선택한다. 선택한 간선을 현재의 신장 트리에 추가했을 때 사이클이 생기지 않는다면 해당 간선을 트리에 추가한다. 위의 과정을 반복하여 신장 트리에 간선을 추가한다. 이 때, 추가되는 간선의 수는 (정점의 개수 -1)이 될 때까지이다. 예제 입력 Kruskal 출력 
[냉부] 올바른 테스트란 무엇인가
@DataJpaTest를 사용하면서 알게된 사실 1. @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 가 없으면 자체적인 임베디드 DB를 사용한다. 그렇게 되면 내가 지정해 놓았던 yml의 DataSources 부분이 실행되지 않고 스프링에서 기본적으로 설정해놓은 임베디드 db가 실행된다. (log에 Start embedded database: 라고 뜬다.) 물론 DataSources에도 url을 'url: jdbc:h2:mem: ' 로 지정해두면 임베디드로 쓸 수 있다. 하지만 이건 내가 직접 지정하고 옵션을 추가할 수 있고 의도해서 사용할 수 있다. 2. JPA를 사용하고 있다면 스크립트를 통한 데이터 초기화 방법을 사용하지 말자. (이걸로 삽질 엄청 많이함) spring.sql.init.mode=never로 지정해두고 data.sql, schema.sql
[Jest] Prisma mocking
Prisma 공식문서에는 단위 테스트 등을 수행할 때 PrismaClient를 모킹하는 방법에 대해 다소 복잡하게 설명하고 있다. 이게 Nestjs의 DI까지 고려하게되면 조금 머리 아파져서 일전에 시행착오를 많이 거쳤던 적이 있었고, 그래서 또 최근([TDD] 외부 라이브러리 테스트)에는 다소 manual하게 직접 모킹 객체를 만들어서 사용하기도 했다. 하지만 Prisma 공식문서에서도 소개하고 있는 jest-mock-extended를 사용하여 비교적 더 간단하게 단위 테스트 내에서 Prisma의 동작을 모킹하는 방법이 있기에 소개한다. 1. jest-mock-extended 설치 pnpm add jest-mock-extended 2. testi
Mockito 사용하기
✏️ Mock 테스트 할 때 필요한 실제 객체를 흉내내는 가짜 객체를 만들어 테스트의 효율을 높히기 위해 사용한다. 서비스 로직의 부하가 많이걸려, 시간도 너무 오래걸리는 경우 서버간 통신이 제대로 되고있는지 확인해야하는 경우 요청을 보낼 API 가 작업중인 경우 등등 ... ✏️ Mock 객체의 종류 📍 Stubbing Mock 객체를 통해 반환될 미리 준비된 답변을 뜻한다. Stub 이라고도 불린다. when method 를 사용해 Stubbing 을 사용한다. when 에 stubing 할 method 를 넣고 method chaining 형식으로 사용된다. 📍 @Mock 가짜 객체를 뜻한다. 객체의 method 를 호출하려면 반드시 stubbing 을 해야한다. 만약 Stubbing 을 생략할경우 Null 또는 0 을 반환한다. 📍 @Sp
[TDD] 3. 외부 라이브러리 테스트
1. Mocking이란? 외부 라이브러리를 테스트할 때는 mocking을 해야한다. 사전적으로 mocking이란 "따라하는 것"이다. 그리고 테스트에서의 mocking도 같은 의미이며, 이때 특정 객체 혹은 함수를 마치 실제로 호출한것처럼 따라하기 위해 사용한다. 유닛 테스트는 작은 범위의 로직이 의도한대로 동작하는지 체크하기 위한 테스트다. 그런데 외부 의존성의 동작 성공 여부에 따라 테스트하려는 대상의 동작을 결과가 달라진다면 테스트를 하기 매우 까다로워진다. 따라서, 외부 의존성은 mocking하여 어느정도 의도한 결과를 항상 내놓도록 만듬으로서 유닛 테스트를 항상 같은 조건에서 시행할 수 있게 된다. 2. 의존성이 주입 Mocking 우선 회원가입 기능 테스트 진행상황을 다시 보자. 다음번 유닛 테스트는 회원 중복 검사인데, 이를 위해서는 데이터베이스에 특정값을 가진 데이터가 존재하는지 질의를 해야한다. 하지만 데이터베이스도 엄연히 외부 의존성이기 때문에

MockBean(파일업로드)
1. 개요 과제로 Post를 만드는과제가 있었다. 파일 업로드를 해야 하고, 이것을 테스트 하는 코드를 작성하였다. 위와 같은 테스트 코드를 작성했다. file.createNewFile(); 을 해야 했던 이유는, 파일이 없으면 NPE 가 발생했기 때문이다. 하지만 동생의 코드 리뷰를 받고서는 테스트코드는 어떠한 상황에서도 돌아가야 한다는 말을 들었다. 즉, 위의 테스트 코드는 컴퓨터의 용량이 모두 찼을 경우에는 돌아가지 않는다는 이야기였다. 그렇다면 가상으로 파일을 만들고, 저장해야 하는 코드가 필요했다. 열심히 찾아서 File을 Mocking 하는 방법을 찾아 봤지만, 똑같이 NPE가 발생했다. 그럴 수밖에 없는 게 Mock의 기본은 빈 객체를 반환하는 것이기 때문이다. 동생에게 다시 물어봤고

SpringBoot - 단위 테스트
💡 기본적인 테스트 개념에 대해 알아보고 Spring에서 사용하는 테스트 방법들에 대해 정리해보고자 한다. > 테스트란? 구현한 프로그램이 올바르게 작동하는지 검사하는 과정 테스트 코드를 작성해두면, 추후에 리팩토링 할 때에 자신감 있게 리팩토링이 가능하다 → 기능이 제대로 동작하는지 바로 확인할 수 있기 때문 기능을 구현하고 테스트 코드를 작성하는 습관을 들이도록 노력해보자 테스트의 종류 단위 테스트 단위 테스트는 프로그램에서 테스트 가능한 가장 작은 부분을 실행하여 예상대로 동작하는지 확인하는 과정이다. 단위 테스트에서 테스트 단위 크기는 절대적으로 정해져 있지는 않지만, 일반적으로 클래스 혹은 메소드 수준으로 정해진다. Solitary vs Sociable Solitary test: TestDouble(Dummy, Fake Stubs, Spies, Mocks)를 사용하여 의존성이 있는 클래스 등을 완벽히

Mockito 기반의 Controller 단위 테스트
Mockito 기반의 Controller 단위 테스트 Mockito 어노테이션 종류 @Mock 가짜 객체를 만들어주는 어노테이션 테스트할 레이어에 필요한 객체를 사용 @Spy 특정 객체의 실제 메소드를 호출 @InjectMocks Mock 객체가 주입되어야 하는 대상 객체 생성 및 주입 Mockito 메서드 doReturn() 가짜 객체가 특정한 값을 반환하는 경우 doNothing() 가짜 객체가 아무 것도 반환하지 않는 경우 void인 경우 doThrow() 가짜 객체가 예외를 발생하는 경우 단위 테스트 작성 의존성 주입 및 HTTP 호출을 위한 MockMVC @InjectMocks 테스트 대상 가짜 객체 주입 Controller @Mock 가짜 객체 생성 Service -

axios 사용기
axios를 사용해 왔던 방법 프론트엔드에서 가장 흔하게 사용하는 라이브러리 중 하나는 axios일 것이다. 나의 팀도 axios를 당연하게 사용하였다. 하지만 사용하다보니 중복되는 코드가 많았고 과연 axios를 유용하게 사용하고 있는것이 맞는지 의문이었다. 매번 설정하는 default setting 기존에는 api한개당 한개의 api 파일이 있었다. 그리고 해당 파일에서 api에 필요한 설정을 해주었으며 필요한 값이 없는 경우 에러를 던지는 코드를 작성해 주었다. 모든 api 함수에 동일하게 작성되었다. 어차피 복붙해서 사용했지만 시간이 지나면서 비효율적이라는 의견이 나왔고 나도 이에 동감했다. 세션 스토리지에 저장하는 인증 토큰과 유저키를 getTodosApi에서 확인하고 값이 없다면 에러를 던졌다. 그리고 axios에서 사용하는 url은 환경변수와 api path를 조합하여 매번 작성했다. 모든 api 호출 함수에서 환경변수값을 참조했다. api