mockito spy and dependency injection :이 방법이 테스트에서 모의 값을 호출하지 않는 문제를 해결합니다.
문제 분석 : Mockito Spy는 직접 인스턴스화와 충돌합니다
단위 테스트에 Mockito를 사용할 때 SPY 기능을 사용하면 실제 객체를 부분적으로 시뮬레이션 할 수 있습니다. 즉, 실제 방법을 호출하거나 특정 방법을 스터브 할 수 있습니다. 그러나 일반적인 함정은 생산 코드 (즉, 테스트중인 메소드)가 의존하는 객체의 인스턴스를 직접 생성 할 때 테스트의 종속 객체에 대해 생성 된 스파이 또는 모의 인스턴스가 적용되지 않는다는 것입니다.
다음 시나리오를 고려하십시오.
원래 생산 코드 스 니펫 :
공개 수업 myservice { public double calculatePrice () { getOptionBidPrice getOptionBidPrice = 새로운 getOptionBidPrice (...); // 문제는 다음과 같습니다. 직접적으로 인스턴스화하면 Double BidPrice = getOptionBidPrice.getBidPrice (); // ... 기타 비즈니스 로직은 BidPrice를 사용합니다 반환 BidPrice * 1.1; // 샘플 계산} } 공개 수업 getOptionBidPrice { // ... 생성자 및 기타 필드 public double getbidPrice () { // 네트워크 요청 또는 복잡한 계산이 포함될 수있는 실제 비즈니스 논리는 0.0을 반환합니다. // 기본 반품 0이 반환되었다고 가정합니다. 0.0 } }
해당 테스트 코드 시도 :
import org.junit.jupiter.api.test; import org.mockito.mockito; 정적 org.mockito.mockito.doreturn 가져 오기; 정적 org.mockito.mockito.spy 가져 오기; static org.junit.jupiter.api.assertions.assertequals 가져 오기; 공개 클래스 myservicetest { @시험 void testCalculatePriceWithSpy () { // getOptionBidPrice를 스파이 시도하십시오 getOptionBidPrice spygetOptionBidPrice = Spy (getOptionBidPrice.class); DORETURN (100.0). 언제 (spygetOptionBidPrice) .getBidPrice (); // Piled GetbidPrice 메소드 // myService 인스턴스를 만들고 myService myService = new MyService (); 이중 결과 = myService.calculatePrice (); // 여기에서, 새로운 getOptionBidPrice 인스턴스는 여전히 내부적으로 생성됩니다. // 예상 결과는 100.0의 파일을 기반으로하지만 실제로는 getOptionBidPrice 0.0의 실제 반환 값을 기반으로 할 수 있습니다. // AsserTequals (110.0, 결과); // 값 기대} }
이 예에서는 테스트에서 spygetoptionbidPrice를 만들고 getbidPrice () 메소드를 쌓았지만 MyService classe CalmulatePrice () 메소드는 내부적으로 새로운 getOptionbidPrice (...)를 통해 새로운 getOptionBidPrice 인스턴스를 생성합니다. 이 새 인스턴스는 테스트에서 생성 된 스파이 인스턴스와 완전히 독립적이므로 CalculatePrice () 메소드는 스파이 인스턴스에 쌓인 메소드보다는 실제 인스턴스의 getbidPrice () 메소드를 호출하여 시뮬레이션 값 100.0이 적용되지 않지만 실제 메소드에 의해 반환되는 0.0을 얻습니다.
해결책 : 의존성 주입 도입
위의 문제를 해결하는 핵심 아이디어는 테스트 된 클래스 (MyService)가 내부적으로 의존성 (getOptionBidPrice)의 인스턴스를 직접 만들도록하는 것입니다. 대신, 종속성 객체는 어떤 식 으로든 테스트 된 클래스에 "주입"되어야합니다. 이 설계 패턴을 의존성 주입 (DI) 이라고합니다.
종속성 주입을 통해 실제 종속성 객체를 생산 코드에 주입하고 종속성 동작에 대한 제어를 달성하기 위해 테스트 코드에 스파이 또는 모의 개체를 주입 할 수 있습니다.
리팩토링 된 생산 코드 :
공개 수업 myservice { 개인 최종 GetOptionBidPrice getOptionBidPrice; // 종속성을 멤버 변수로 선언합니다. // 생성자를 통해 종속성을 주입 공개 myService (getOptionBidPrice getOptionBidPrice) { this.getOptionBidPrice = getOptionBidPrice; } public double calculatePrice () { Double BidPrice = getOptionBidPrice.getBidPrice (); // 주입 된 종속성 인스턴스 호출 // ... 기타 비즈니스 로직을 사용합니다 BidPrice 반환 BidPrice * 1.1; } } // getOptionBidPrice 클래스는 변경되지 않은 공개 클래스 getOptionBidPrice { // ... 생성자 및 기타 필드 public double getbidPrice () { 반환 0.0; } }
리팩토링 된 테스트 코드 :
import org.junit.jupiter.api.test; import org.mockito.mockito; 정적 org.mockito.mockito.doreturn 가져 오기; 정적 org.mockito.mockito.spy 가져 오기; static org.junit.jupiter.api.assertions.assertequals 가져 오기; 공개 클래스 myservicetest { @시험 void testCalculatePriceWithInjectedSpy () { // spy 인스턴스 생성 및 파일 spygetOptionbidPrice = spy (getOptionBidPrice.class); DORETURN (100.0). 언제 (spygetOptionBidPrice) .getBidPrice (); // 스파이 인스턴스를 myService에 주입 myService myService = new MyService (spygetOptionBidPrice); 이중 결과 = myService.calculatePrice (); // 이제 CalculatePrice는 주입 된 스파이 인스턴스 AsserTequals의 getbidPrice () 메소드를 호출합니다 (110.0, "계산 결과는 반박 된 입찰 가격을 기준으로해야한다"); // getbidPrice 메소드가 mockito.verify (spygetOptionBidPrice) .getBidPrice (); } // 제작 코드에서 MyService를 사용하는 방법 public static void main (String [] args) { // 생산 환경에서 실제 getOptionBidPrice 인스턴스를 주입합니다. getOptionBidPrice RevementOptionBidPrice = 새로운 getOptionBidPrice (/* 실제 매개 변수*/); MyService realmyservice = New MyService (readgetOptionbidPrice); Double ProductionResult = realmyservice.calculatePrice (); System.out.println ( "생산 환경 계산 결과 :"ProductionResult); } }
생성자 주입 (가장 일반적인 의존성 주입 방법 중 하나)을 통해, MyService는 더 이상 getOptionBidPrice 인스턴스를 생성 할 책임이 없지만 외부에서 제공됩니다. 테스트에서 우리는 스파이 사례를 제공합니다. 생산 환경에서는 실제 사례를 제공합니다. 이러한 방식으로, 테스트는 MyService가 의존하는 getoptionbidPrice의 동작을 완전히 제어 할 수 있습니다.
메모 및 요약
- 의존성 주입의 중요성 : 의존성 주입은 테스트에서 시뮬레이션 문제를 해결할뿐만 아니라 현대 소프트웨어 설계의 핵심 원칙이기도합니다. 코드의 모듈성, 테스트 가능성, 유지 관리 및 확장 성을 향상시킵니다. 클래스가 다른 클래스에 의존 해야하는 경우, 클래스 내부에서 직접 작성하는 대신 생성자, 세터 방법 또는 인터페이스를 통해 이러한 종속성을 주입하는 것이 선호됩니다.
- 스파이 및 모의 선택 :
- 모의 : 일반적으로 인터페이스 나 클래스를 완전히 시뮬레이션하는 데 사용됩니다. 시스템의 모든 방법은 기본적으로 실제 논리를 수행하지 않으며 명시 적으로 쌓여 있어야합니다. 테스트 장치가 외부에서 완전히 분리 된 시나리오에 적합합니다.
- 스파이 : 실제 객체를 부분적으로 시뮬레이션하는 데 사용되며, 끊임없는 방법은 실제 논리를 수행합니다. 실제 객체의 대부분의 기능을 테스트해야하며 테스트하기 어려운 몇 가지를 제어하거나 시간이 많이 걸리는 방법 만 제어하는 시나리오에 적합합니다.
- 이 경우 Spy를 사용하는 것이 적절합니다. 왜냐하면 우리는 getOptionbidPrice의 대부분의 동작이 변경되지 않은 상태로 유지되기를 원하고 getbidPrice () 메소드 만 쌓기 때문입니다.
- 세분성 테스트 : 단위 테스트는 단일 단위 (일반적으로 클래스 또는 방법)의 동작에 중점을두고 종속성을 분리해야합니다. 조롱 또는 스파이 종속성을 통해 테스트의 초점이 테스트 결과를 방해하는 외부 요인을 피하면서 테스트중인 장치로 제한되도록 할 수 있습니다.
- 테스트중인 방법 내부에서 종속성을 생성하지 마십시오. 이는 단위 테스트를 어렵게 만드는 일반적인 방지 방지입니다. 메소드가 내부적으로 복잡한 종속성을 생성하는 경우이 방법은 생성하는 종속성과 밀접하게 연결되어 있기 때문에 별도로 테스트하기가 어렵습니다.
- 검증 동작 : 스파이 또는 모의를 사용한 후 리턴 값을 확인하는 것 외에도 Mockito.Verify ()는 조롱 된 개체의 메소드가 올바르게 호출되는지 여부와 호출 및 매개 변수의 수가 예상되는지 여부를 확인하는 데 사용해야합니다.
의존성 주입 패턴을 채택하고 Mockito Spy의 작동 방식을 이해함으로써 개발자는보다 강력하고 테스트하는 응용 프로그램을 더 쉽게 구축 할 수 있습니다.
위 내용은 mockito spy and dependency injection :이 방법이 테스트에서 모의 값을 호출하지 않는 문제를 해결합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undress AI Tool
무료로 이미지를 벗다

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

JDBC 트랜잭션을 올바르게 처리하려면 먼저 자동 커밋 모드를 끄고 여러 작업을 수행 한 다음 결과에 따라 커밋 또는 롤백을 수행해야합니다. 1. 트랜잭션을 시작하려면 Conn.SetAutoCommit (False)에게 전화하십시오. 2. 인서트 및 업데이트와 같은 여러 SQL 작업을 실행합니다. 3. 모든 작업이 성공한 경우 Conn.commit ()에게 전화하여 데이터 일관성을 보장하기 위해 예외가 발생하면 Conn.Rollback ()에게 전화하십시오. 동시에, 재 시도는 리소스를 관리하고, 예외를 올바르게 처리하고, 연결 유출을 피하기 위해 긴밀한 연결을 사용하는 데 사용해야합니다. 또한 연결 풀을 사용하고 부분적으로 롤백을 달성하기 위해 저장 포인트를 설정하고 성능을 향상시키기 위해 거래를 가능한 한 짧게 유지하는 것이 좋습니다.

이전 날짜 및 달력 클래스를 대체하기 위해 Java.Time 패키지의 클래스를 사용하십시오. 2. LocalDate, LocalDateTime 및 LocalTime을 통해 현재 날짜와 시간을 얻으십시오. 3. () 메소드를 사용하여 특정 날짜와 시간을 만듭니다. 4. 플러스/마이너스 방법을 사용하여 시간을 불안정하게 늘리고 감소시킵니다. 5. ZonedDateTime 및 Zoneid를 사용하여 시간대를 처리하십시오. 6. DateTimeFormatter를 통해 형식 및 구문 분석 날짜 문자열; 7. 필요한 경우 이전 날짜 유형과 호환되도록 즉시 사용하십시오. 현대 Java의 날짜 처리는 명확하고 불변의 선형을 제공하는 Java.Timeapi 사용에 우선 순위를 부여해야합니다.

setupamaven/gradleProjectwithJax-rsddependencies likejersey; 2. createarestresourceUsingAnnotationsSuchas@pathand@get;

Pre-FormancetArtUptimeMoryUsage, Quarkusandmicronautleadduetocompile-timeprocessingandgraalvsupport, withquarkusoftenperforminglightbetterine serverless sinarios.2.thyvelopecosyste,

의존성 (DI) ISADESIGNPATTORNWHEREWHEDROUDIVESTESTESTETESTERGROWCONSTRUCTOR, 2.SPRINGFRAMEWWERTHUSENONTATIONS와 같은@autowiredWithjava 기반 CONCUTTATIONS LIKERWITHCONSTRUCTOR, ORFIELDINGESS.2.SPRINGFRAMEWWERTHUSENNOTATIONS

성능 분석 도구를 사용하여 병목 현상을 찾고 개발 및 테스트 단계에서 VisualVM 또는 JProfiler를 사용하며 생산 환경에서 Async-Profiler에 우선 순위를 부여합니다. 2. 객체 생성을 줄이고, 개체를 재사용하고, StringBuilder를 사용하여 문자열 스 플라이 싱을 교체하고, 적절한 GC 전략을 선택하십시오. 3. 장면에 따라 수집 사용을 최적화하고 초기 용량을 선택하고 사전 설정합니다. 4. 동시성 최적화, 동시 컬렉션을 사용하고, 잠금 세분화를 줄이고, 스레드 풀을 합리적으로 설정하십시오. 5. JVM 매개 변수 조정, 합리적인 힙 크기 및 저도 가비지 수집기를 설정하고 GC 로그를 활성화합니다. 6. 코드 레벨에서 반사를 피하고, 래퍼 클래스를 기본 유형으로 바꾸고, 초기화를 지연시키고, 최종 및 정적을 사용하십시오. 7. JMH와 결합 된 지속적인 성능 테스트 및 모니터링

Maven은 Java 프로젝트 관리 및 건설을위한 표준 도구입니다. 답은 POM.XML을 사용하여 프로젝트 구조, 종속성 관리, 건설 라이프 사이클 자동화 및 플러그인 확장을 표준화한다는 사실에 있습니다. 1. pom.xml을 사용하여 groupId, artifactid, 버전 및 종속성을 정의하십시오. 2. MVNClean, 컴파일, 테스트, 패키지, 설치 및 배포와 같은 마스터 코어 명령; 3. 종속성 버전 및 충돌을 관리하기 위해 종속성 관리 및 제외를 사용합니다. 4. 다중 모듈 프로젝트 구조를 통해 대규모 응용 프로그램을 구성하고 부모 POM에 의해 균일하게 관리됩니다. 5.

thejvmenablesjava의 "WriteOnce, Runynywhere"기능은 비록 excodecodethroughfourmaincomponents : 1. theclassloadersubsystemloads, 링크, 및 intinitializes.classfilesusingbootsprap, extension, andapplicationclassloaders, ensuringsecureandlazyclasloa
