불필요한 스터빙 예외 해결 방법
내 코드는 다음과 같습니다.
@RunWith(MockitoJUnitRunner.class)
public class MyClass {
private static final String code ="Test";
@Mock
private MyClassDAO dao;
@InjectMocks
private MyClassService Service = new MyClassServiceImpl();
@Test
public void testDoSearch() throws Exception {
final String METHOD_NAME = logger.getName().concat(".testDoSearchEcRcfInspections()");
CriteriaDTO dto = new CriteriaDTO();
dto.setCode(code);
inspectionService.searchEcRcfInspections(dto);
List<SearchCriteriaDTO> summaryList = new ArrayList<SearchCriteriaDTO>();
inspectionsSummaryList.add(dto);
when(dao.doSearch(dto)).thenReturn(inspectionsSummaryList);//got error in this line
verify(dao).doSearchInspections(dto);
}
}
나는 예외보다 낮아지고 있다.
org.mockito.exceptions.misusing.UnnecessaryStubbingException: Unnecessary stubbings detected in test class: Test Clean & maintainable test code requires zero unnecessary code. Following stubbings are unnecessary (click to navigate to relevant line of code): 1. -> at service.Test.testDoSearch(Test.java:72) Please remove unnecessary stubbings or use 'silent' option. More info: javadoc for UnnecessaryStubbingException class. at org.mockito.internal.exceptions.Reporter.formatUnncessaryStubbingException(Reporter.java:838) at org.mockito.internal.junit.UnnecessaryStubbingsReporter.validateUnusedStubs(UnnecessaryStubbingsReporter.java:34) at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:49) at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:103) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
해결 방법을 알려주세요.
먼저 테스트 로직을 확인해야 합니다.보통 3가지 경우가 있습니다.첫째, 잘못된 방법을 조롱하고 있습니다(오타를 치거나 테스트된 코드를 변경하여 조롱된 방법을 더 이상 사용하지 않도록 했습니다).둘째, 이 메서드가 호출되기 전에 테스트가 실패합니다.셋째, 코드 내 어딘가에서 브랜치를 바꾸면 논리가 잘못되어 조롱된 메서드가 호출되지 않습니다.
이것이 첫 번째 경우라면 항상 코드에서 사용되는 방법으로 조롱된 방법을 변경해야 합니다.두 번째와 세 번째에 따라 다르죠.보통 이 모형이 쓸모없으면 삭제해야 합니다.단, 파라미터화된 테스트에 특정 케이스가 있을 수 있습니다.이러한 테스트에서는 다른 경로를 사용하거나 더 일찍 실패합니다.그런 다음 이 테스트를 두 개 이상의 개별 테스트로 나눌 수 있지만 항상 보기 좋은 것은 아닙니다.3개의 인수 공급자가 있는 3가지 테스트 방법은 테스트를 읽을 수 없는 것처럼 보이게 할 수 있습니다.이 경우 JUnit 4의 경우 다음 중 하나를 사용하여 이 예외를 사일런트합니다.
@RunWith(MockitoJUnitRunner.Silent.class)
주석 또는 규칙 접근 방식을 사용하는 경우
@Rule
public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.LENIENT);
또는 (동일한 동작)
@Rule
public MockitoRule rule = MockitoJUnit.rule().silent();
5에서는 JUnit 5에서 제공하는 하여 이 수 .mockito-junit-jupiter
★★★★★★★★★★★★★★★★★★:
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class JUnit5MockitoTest {
}
@RunWith(MockitoJUnitRunner.class)
@RunWith(MockitoJUnitRunner.Silent.class)
.
나 the the for the the for@Rule
@RunWith(MockitoJUnitRunner.Silent.class)
제안은 효과가 있었다.2. mockito-core 2.23.0으로 였습니다.
해서 될 것 같아요.UnnecessaryStubbingException
Mockito.lenient().when(mockedService.getUserById(any())).thenReturn(new User());
다음 대신:
when(mockedService.getUserById(any())).thenReturn(new User());
테스트 코드를 보는 것은 당연합니다만, 우선 컴파일을 실시해, 테스트를 실행할 필요가 있었습니다.
침묵은 해결책이 아니다.너는 시험에서 모의고사를 고쳐야 한다.공식 문서는 여기를 참조하십시오.
불필요한 스터브는 테스트 실행 중에 실현되지 않은 스터브 방식 콜입니다(MockitoHint도 참조).다음 예시를 나타냅니다.
//code under test:
...
String result = translator.translate("one")
...
//test:
...
when(translator.translate("one")).thenReturn("jeden"); // <- stubbing realized during code execution
when(translator.translate("two")).thenReturn("dwa"); // <- stubbing never realized
...
테스트 실행 중 테스트 대상 코드에서 stubbed 메서드 중 하나가 실현되지 않았습니다.스트레이 스터빙은 개발자의 감시, 복사 붙여넣기 또는 테스트/코드를 이해하지 못하는 효과일 수 있습니다.어느 쪽이든 개발자는 불필요한 테스트 코드를 갖게 됩니다.코드베이스를 깨끗하고 유지보수가 가능한 상태로 유지하려면 불필요한 코드를 삭제해야 합니다.그렇지 않으면 테스트는 읽고 추론하기가 더 어려워집니다.
미사용 스터빙 검출에 대한 자세한 내용은 MockitoHint 를 참조하십시오.
when(dao.doSearch(dto)).thenReturn(inspectionsSummaryList);//got error in this line
verify(dao).doSearchInspections(dto);
그when
여기서, 모크가 동작하도록 설정합니다.단, 이 행 이후로는 이 모의실험을 사용하지 않습니다.verify
) Mockito는 경고합니다.when
행은 무의미합니다.논리적인 오류를 범한 건 아닐까요?
교체하다
@RunWith(MockitoJUnitRunner.class)
와 함께
@RunWith(MockitoJUnitRunner.Silent.class)
또는 제거@RunWith(MockitoJUnitRunner.class)
또는 불필요한 조롱 콜(부정 스텁으로 간주)을 코멘트합니다.
다른 사람이 지적한 것처럼 보통 메서드콜을 불필요하게 스텁하고 있는 회선을 삭제하는 것이 가장 간단합니다.
저 같은 경우에는...@BeforeEach
대부분 관련이 있었어요이 방법이 사용되지 않은 유일한 테스트에서는 다음과 같이 모크를 재설정했습니다.
myMock.reset()
이것이 다른 사람들에게도 같은 문제에 도움이 되기를 바랍니다.
(같은 모의에 여러 개의 조롱된 콜이 있는 경우 호출되지 않은 메서드를 제외한 다른 메서드는 모두 조롱해야 하므로 이 또한 불편할 수 있습니다.)
이것은 이미 이 코멘트에서 지적되고 있습니다만, 간과하기 쉽다고 생각합니다.다음과 같은 문제가 발생할 수 있습니다.UnnecessaryStubbingException
JUnit 4 테스트클래스를 JUnit 5 테스트클래스로 변환하기만 하면@Before
와 함께@BeforeEach
또, 그 셋업 방법으로 스터브를 실행했을 경우, 적어도1개의 테스트 케이스에서는 실현되지 않습니다.
이 Mockito 스레드에는 그에 대한 자세한 정보가 있습니다.기본적으로 테스트 실행에서는@Before
그리고.@BeforeEach
.와 함께@Before
테스트 케이스가 스터빙을 실현했을 경우,@BeforeEach
모든 케이스가 그래야 합니다.
셋업을 해체하지 않으면@BeforeEach
(위의 코멘트가 올바르게 지적한 바와 같이) 전체 테스트 클래스에 대해 관대한 모드를 활성화하는 대신 다른 옵션이 있습니다.그 스텁빙은 단순히 테스트 클래스 내에서만 만들 수 있습니다.@BeforeEach
개별적으로 사용하는 관대한 방법lenient()
.
스택 트레이스의 일부를 보면, 스텁으로 되어 있는 것처럼 보입니다.dao.doSearch()
다른 곳에서.같은 방식의 stub을 반복적으로 작성하는 것에 가깝습니다.
Following stubbings are unnecessary (click to navigate to relevant line of code):
1. -> at service.Test.testDoSearch(Test.java:72)
Please remove unnecessary stubbings or use 'silent' option. More info: javadoc for UnnecessaryStubbingException class.
다음 테스트 클래스를 예로 들 수 있습니다.
@RunWith(MockitoJUnitRunner.class)
public class SomeTest {
@Mock
Service1 svc1Mock1;
@Mock
Service2 svc2Mock2;
@InjectMock
TestClass class;
//Assume you have many dependencies and you want to set up all the stubs
//in one place assuming that all your tests need these stubs.
//I know that any initialization code for the test can/should be in a
//@Before method. Lets assume there is another method just to create
//your stubs.
public void setUpRequiredStubs() {
when(svc1Mock1.someMethod(any(), any())).thenReturn(something));
when(svc2Mock2.someOtherMethod(any())).thenReturn(somethingElse);
}
@Test
public void methodUnderTest_StateUnderTest_ExpectedBehavior() {
// You forget that you defined the stub for svcMock1.someMethod or
//thought you could redefine it. Well you cannot. That's going to be
//a problem and would throw your UnnecessaryStubbingException.
when(svc1Mock1.someMethod(any(),any())).thenReturn(anyThing);//ERROR!
setUpRequiredStubs();
}
}
필요한 경우 당신의 테스트를 stub에 리팩터링하는 것을 고려해보고 싶습니다.
음, 내 경우, 모키토 에러는 나에게 실제 방법을 호출하라고 말했다.when
★★★★★★★★★★★★★★★★★」whenever
우리가 방금 조롱했던 조건을 호출한 게 아니었으니까 모키토는 그걸 불필요한 스텁이나 코드로 보고한 거야
에러가 발생했을 때의 상황을 다음에 나타냅니다.
@Test
fun `should return error when item list is empty for getStockAvailability`() {
doAnswer(
Answer<Void> { invocation ->
val callback =
invocation.arguments[1] as GetStockApiCallback<StockResultViewState.Idle, StockResultViewState.Error>
callback.onApiCallError(stockResultViewStateError)
null
}
).whenever(stockViewModelTest)
.getStockAvailability(listOf(), getStocksApiCallBack)
}
그리고 나는 그 방법을 조롱하기 위해 진술서에 언급된 실제 방법을 호출했다.
.stockViewModelTest.getStockAvailability(listOf(), getStocksApiCallBack)
@Test
fun `should return error when item list is empty for getStockAvailability`() {
doAnswer(
Answer<Void> { invocation ->
val callback =
invocation.arguments[1] as GetStockApiCallback<StockResultViewState.Idle, StockResultViewState.Error>
callback.onApiCallError(stockResultViewStateError)
null
}
).whenever(stockViewModelTest)
.getStockAvailability(listOf(), getStocksApiCallBack)
//called the actual method here
stockViewModelTest.getStockAvailability(listOf(), getStocksApiCallBack)
}
이제 되네.
대신 이 스타일을 사용하는 경우:
@Rule
public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
다음으로 대체:
@Rule
public MockitoRule rule = MockitoJUnit.rule().silent();
는 ★★★★★★★★★★★★★★★★★★★★★★★★★.UnnecessaryStubbingException
가 ★★★★★★★★★★★★★★★★를 사용하려고 했을 때when
메서드를 지정합니다. Mockito.lenient()
예외를 무음 처리했지만 테스트 결과가 올바르지 않았습니다.
Spy 오브젝트의 경우 메서드를 직접 호출해야 한다.
@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
class ArithmTest {
@Spy
private Arithm arithm;
@Test
void testAddition() {
int res = arithm.add(2, 5);
// doReturn(7).when(arithm).add(2, 5);
assertEquals(res, 7);
}
}
대규모 프로젝트의 경우 이러한 예외를 수정하기가 어렵습니다. 「」를 하고,Silent
을 사용하다불필요한 스터빙을 모두 삭제하기 위한 스크립트를 작성했습니다.
https://gist.github.com/cueo/da1ca49e92679ac49f808c7ef594e75b
됩니다.mvn
를 사용하여 이러한 .regex는 regex에 의해 처리됩니다.
any()를 any()를 .@RunWith(MockitoJUnitRunner.class)
@RunWith(MockitoJUnitRunner.Silent.class)
.
언급URL : https://stackoverflow.com/questions/42947613/how-to-resolve-unneccessary-stubbing-exception
'source' 카테고리의 다른 글
IntelliJ IDEA를 사용하여 Java 프로젝트에서 Jenkinsfile 구문 강조 표시 (0) | 2022.09.03 |
---|---|
인터페이스, 구현 또는 둘 다에 대해 코멘트하시겠습니까? (0) | 2022.09.03 |
java.lang 잡는 중Out Of Memory Error? (0) | 2022.09.03 |
다양한 64비트 데이터 모델과 비교하여 32비트(size_t)의 사이즈는 어떻게 됩니까? (0) | 2022.09.03 |
Closeable 구현 또는 AutoCloseable 구현 (0) | 2022.09.03 |