@InjectMocks를 사용하여 String 속성 주입
스프링 MVC가 있습니다.@Controller이 시공자와 함께:
@Autowired
public AbcController(XyzService xyzService, @Value("${my.property}") String myProperty) {/*...*/}
이 컨트롤러에 대해 독립 실행형 장치 테스트를 작성하려고 합니다.
@RunWith(MockitoJUnitRunner.class)
public class AbcControllerTest {
@Mock
private XyzService mockXyzService;
private String myProperty = "my property value";
@InjectMocks
private AbcController controllerUnderTest;
/* tests */
}
다른 방법이 없을까요?@InjectMocks내 String 속성을 주입하라고요?String은 불변이기 때문에 조롱할 수 없다는 것을 알지만, 여기에 그냥 일반 String을 주입해도 될까요?
@InjectMocks이 경우 기본적으로 null을 주입합니다.@Mock내가 예외를 적용한다면 이해할 수 있습니다.myProperty. 제가 놓친 주석 중에 "이 정확한 객체를 조롱하는 것이 아니라 주입하라"는 의미의 주석이 또 있습니까?
모키토로 할 수는 없지만 Apache Commons는 내장된 유틸리티 중 하나를 사용하여 이를 수행할 수 있는 방법이 있습니다.Mockito가 나머지 모의실험을 주입한 후 테스트 케이스가 실행되기 전에 Junit에서 실행되는 함수에 이 함수를 넣을 수 있습니다.
@InjectMocks
MyClass myClass;
@Before
public void before() throws Exception {
FieldUtils.writeField(myClass, "fieldName", fieldValue, true);
}
Spring을 사용하고 계시기 때문에.org.springframework.test.util.ReflectionTestUtils로부터spring-test모듈.객체에 필드를 설정하거나 클래스에 정적 필드를 설정할 때(다른 유틸리티 메서드와 함께) 깔끔하게 래핑합니다.
@RunWith(MockitoJUnitRunner.class)
public class AbcControllerTest {
@Mock
private XyzService mockXyzService;
@InjectMocks
private AbcController controllerUnderTest;
@Before
public void setUp() {
ReflectionTestUtils.setField(controllerUnderTest, "myProperty",
"String you want to inject");
}
/* tests */
}
모키토를 이용해서는 안 돼요 왜냐면 당신 말대로String가final조롱할 수 없습니다
있습니다.@Spy실제 물체에 작용하는 주석이지만 다음과 같은 한계를 가지고 있습니다.@Mock, 따라서 당신은 당신이 a를 염탐할 수 없습니다.String.
모키토에게 조롱이나 스파이 행위를 하지 않고 그 가치를 주입하라고 말할 주석은 없습니다.그래도 좋은 기능이 될 것 같습니다.아마도 모키토 깃허브 저장소에서 제안해 보세요.
코드를 변경하지 않으려면 컨트롤러를 수동으로 인스턴스화해야 합니다.
순수 주석 기반 테스트를 수행할 수 있는 유일한 방법은 컨트롤러를 리팩터하는 것입니다.속성 하나만 포함하는 사용자 지정 개체를 사용하거나 속성이 여러 개인 구성 클래스를 사용할 수도 있습니다.
@Component
public class MyProperty {
@Value("${my.property}")
private String myProperty;
...
}
이것은 컨트롤러에 주입될 수 있습니다.
@Autowired
public AbcController(XyzService xyzService, MyProperty myProperty) {
...
}
그러면 이걸 조롱하고 주사를 놓으시면 됩니다.
@RunWith(MockitoJUnitRunner.class)
public class AbcControllerTest {
@Mock
private XyzService mockXyzService;
@Mock
private MyProperty myProperty;
@InjectMocks
private AbcController controllerUnderTest;
@Before
public void setUp(){
when(myProperty.get()).thenReturn("my property value");
}
/* tests */
}
이것은 아주 간단하지는 않지만, 적어도 약간의 스텁(stub)이 있는 순수한 주석 기반의 테스트를 가질 수 있을 것입니다.
그런 경우에는 @InjectMocks를 사용하지 마십시오.
행:
@Before
public void setup() {
controllerUnderTest = new AbcController(mockXyzService, "my property value");
}
솔루션은 간단합니다.개체 유형에 대해 생성자 주입을 수행해야 하지만 원시/최종 종속성의 경우 설정자 주입을 사용하면 됩니다. 이 시나리오에서는 괜찮습니다.
그래서 이것은:
public AbcController(XyzService xyzService, @Value("${my.property}") String myProperty) {/*...*/}
다음으로 변경됨:
@Autowired
public AbcController(XyzService xyzService) {/*...*/}
@Autowired
public setMyProperty(@Value("${my.property}") String myProperty){/*...*/}
.@Mock시험 시 주사는 다음과 같이 간단합니다.
@Mock
private XyzService xyzService;
@InjectMocks
private AbcController abcController;
@BeforeMethod
public void setup(){
MockitoAnnotations.initMocks(this);
abcController.setMyProperty("new property");
}
그 정도면 충분합니다.> ㅇㅇReflections권장되지 않습니다!
생산코드에 리플렉션이 사용되는 것을 최대한 피하시기 바랍니다!!
.Jan Groot다를 해야 하기 에 매우 .@Mock@InjectMocks그리고 초기화한 후 수동으로 주입해야 합니다. 2개의 의존성의 경우 쉽게 들리지만 7개의 의존성의 경우 코드가 악몽이 됩니다(아래 참조).
private XyzService xyzService;
private AbcController abcController;
@BeforeMethod
public void setup(){ // NIGHTMARE WHEN MORE DEPENDENCIES ARE MOCKED!
xyzService = Mockito.mock(XyzService.class);
abcController = new AbcController(xyzService, "new property");
}
사용할 수 있는 것은 org.mockito 입니다.내부의 util, 반사화이트박스
- "AbcController" 클래스 생성기 리팩터
Test class "before" 메서드에서 Whitebox.setInternalState 메서드를 사용하여 원하는 문자열을 지정합니다.
@Before public void setUp(){ Whitebox.setInternalState(controllerUnderTest, "myProperty", "The string that you want"); }
코드를 변경하지 않으려면 Reflection을 사용합니다.TestUtils.setField 메서드 Mockito로 봄에 자동으로 연결된 @Value 필드를 mocking하려면 어떻게 해야 합니까?
TL;DR
@Autowired
@InjectMocks
private AbcController controllerUnderTest;
설명:얼마나 간단하면서도 까다로웠는지 알면 놀랄 것입니다.@Autowired 및 @InjectMock 주석을 함께 사용해 보십시오.
이를 통해 실제 개체가 먼저 로드되고 스파이나 조롱이 필요한 개체가 주입됩니다.실제 개체는 속성을 통해 이미 입력된 값을 갖게 됩니다.
언급URL : https://stackoverflow.com/questions/36084559/injecting-a-string-property-with-injectmocks
'programing' 카테고리의 다른 글
| 적절한 인수를 사용하여 C에서 execl()을 호출하는 방법은 무엇입니까? (0) | 2023.09.27 |
|---|---|
| brew link mysql이 완료되지 않았습니다. (0) | 2023.09.27 |
| Oracle 테이블 열 문자 집합을 보려면 어떻게 해야 합니까? (0) | 2023.09.27 |
| 함수 내부의 전역 변수 값을 변경하는 방법 (0) | 2023.09.27 |
| 일부 값을 반환하는 저장 루틴을 만들 수 없습니다. (0) | 2023.09.27 |