programing

Mockito - Nullpointerstubbing 메서드에서의 예외

newsource 2022. 11. 26. 08:37

Mockito - Nullpointerstubbing 메서드에서의 예외

그래서 저는 자바 스프링 프로젝트를 위한 시험을 쓰기 시작했습니다.

제가 사용하는 것은 JUnit과 Mockito입니다.when()...return() 옵션을 사용하면 시뮬레이션 없이 서비스를 모킹할 수 있다고 합니다.그래서 제가 하고 싶은 것은 다음과 같이 설정하는 것입니다.

when(classIwantToTest.object.get().methodWhichReturnsAList(input))thenReturn(ListcreatedInsideTheTestClass)  

하지만 언제가 되든 간에 항상 Nullpointer가 있어요.예외. 입력은 늘이기 때문에 물론 말이 됩니다.

또한 오브젝트에서 다른 메서드를 조롱하려고 할 때:

when(object.method()).thenReturn(true)

여기서 Nullpointer도 얻을 수 있습니다.메서드에는 변수가 필요하지만 설정되지 않았기 때문입니다.

단, when()을 사용하고 싶습니다.그런 다음 Return()을 눌러 이 변수를 만드는 등의 작업을 수행합니다.어떤 클래스가 이 메서드를 호출하면 반드시 true 또는 위의 목록을 반환해야 합니다.

기본적으로 제 쪽에서 오해하고 있는 건가요, 아니면 뭔가 다른 문제가 있는 건가요?

코드:

public class classIWantToTest implements classIWantToTestFacade{
        @Autowired
        private SomeService myService;

        @Override
        public Optional<OutputData> getInformations(final InputData inputData) {
            final Optional<OutputData> data = myService.getListWithData(inputData);
            if (data.isPresent()) {
                final List<ItemData> allData = data.get().getItemDatas();
                    //do something with the data and allData
                return data;
            }

            return Optional.absent();
        }   
}

제 시험 수업은 다음과 같습니다.

public class Test {

    private InputData inputdata;

    private ClassUnderTest classUnderTest;

    final List<ItemData> allData = new ArrayList<ItemData>();

    @Mock
    private DeliveryItemData item1;

    @Mock
    private DeliveryItemData item2;



    @Mock
    private SomeService myService;


    @Before
    public void setUp() throws Exception {
        classUnderTest = new ClassUnderTest();
        myService = mock(myService.class); 
        classUnderTest.setService(myService);
        item1 = mock(DeliveryItemData.class);
        item2 = mock(DeliveryItemData.class);

    }


    @Test
    public void test_sort() {
        createData();
        when(myService.getListWithData(inputdata).get().getItemDatas());

        when(item1.hasSomething()).thenReturn(true);
        when(item2.hasSomething()).thenReturn(false);

    }

    public void createData() {
        item1.setSomeValue("val");
        item2.setSomeOtherValue("test");

        item2.setSomeValue("val");
        item2.setSomeOtherValue("value");

        allData.add(item1);
        allData.add(item2);


}

, 제가 고민하고 있는 였습니다.제 문제는 제 메서드를 호출하는 것이었습니다.any()anyInt()다음 중 하나:

doAnswer(...).with(myMockObject).thisFuncTakesAnInt(any())

그래서 그걸 다음으로 바꿨어요.

doAnswer(...).with(myMockObject).thisFuncTakesAnInt(anyInt())

그게 왜 Null Pointer를 만들었는지 모르겠다.예외.어쩌면 이게 다음 불쌍한 영혼에게 도움이 될지도 몰라.

아직 스터브하지 않은 메서드의 기본 반환값은 다음과 같습니다.false메서드의 과 ""를 의 빈 맵"null렇지지그

은, 「하다」내의 됩니다.when(...) '예'는 '예'입니다when(myService.getListWithData(inputData).get())는 Null Null 포인터를 발생시킵니다. 이유는 다음과 같습니다.myService.getListWithData(inputData)null단 한 안 눌렀어 - 단 한 번도 안 눌렀어요.

1가지 옵션은 모든 중간 리턴 값에 대해 mock을 생성하여 사용하기 전에 stub하는 것입니다.예를 들어 다음과 같습니다.

ListWithData listWithData = mock(ListWithData.class);
when(listWithData.get()).thenReturn(item1);
when(myService.getListWithData()).thenReturn(listWithData);

mock을 할 때 null이 mock을 할 수 . null은 null입니다. mock은 null입니다.RETURNS_DEEP_STUBS

SomeService myService = mock(SomeService.class, Mockito.RETURNS_DEEP_STUBS);
when(myService.getListWithData().get()).thenReturn(item1);

당신은 모키토의 자바독을 읽어야 합니다.RETURNS_DEEP_STUBS: 자세한 설명과 사용법에 대한 경고가 있습니다.

이게 도움이 됐으면 좋겠어요.예시 코드에는 아사트문 또는 검증문이 누락되어 있고, 모크에서 세터를 호출하는 등의 문제가 더 많은 것 같습니다(이는 영향을 주지 않습니다).

저도 같은 문제가 있었는데 단순히 @RunWith를 사용하여 수업에 주석을 제대로 달지 않은 것이 문제였습니다.이 예에서는 다음 사항을 확인합니다.

@RunWith(MockitoJUnitRunner.class)
public class Test {
...

그렇게 하자 Null Pointer는예외는 사라졌다.

장래의 독자에게 있어서, Mock을 사용하는 경우에 NPE가 발생하는 또 하나의 원인은, 다음과 같이 Mock을 초기화하지 않는 것입니다.

@Mock
SomeMock someMock;

@InjectMocks
SomeService someService;

@Before
public void setup(){
    MockitoAnnotations.initMocks(this); //without this you will get NPE
}

@Test
public void someTest(){
    Mockito.when(someMock.someMethod()).thenReturn("some result");
   // ...
}

또한 모든 주석에는 JUnit을 사용해야 합니다.@Test from test로 테스트를 만든 적이 있습니다.NG로 인해 @Before가 작동하지 않았습니다(테스트 중).NG 주석은 @BeforeTest)입니다.

가 NPE에 는 NPE를 사용하고 입니다.Mockito.any() 변종을 에러가 없어집니다.mockito에서는 에러.

인 것을 하려면 , 「원시적인 것」이 필요합니다.long로서 「」를 사용하는 「」를 사용합니다.any() 더 으로 말하면, ', 하다, 하다, 하다, 하다, 하다, 하다'로 해야 합니다any(Long.class) ★★★★★★★★★★★★★★★★★」Mockito.anyLong().

그게 도움이 됐으면 좋겠어요.

이것이 내가 가지고 있는 문제에 가장 가까운 결과이며, 적절한 답을 찾지 못한 첫 번째 결과이기 때문에, 미래의 불쌍한 사람들을 위해 여기에 해결책을 게시할 것이다.

any()조롱된 클래스 메서드가 원시 파라미터를 사용하는 경우에는 작동하지 않습니다.

 public Boolean getResult(String identifier, boolean switch)

위의 경우 OP와 동일한 문제가 발생합니다.

솔루션, 포장만 하면 됩니다.

 public Boolean getResult(String identifier, Boolean switch)

후자는 NPE를 해결합니다.

  • 이 방법을 선택한 경우 프로덕션 코드에 Boolean에 대한 null체크를 포함할 수 있습니다(credit: Ridculy에 의해 부팅됨).

반드시 모크를 초기화해 주세요.

JUnit4@Before

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
}

JUnit5@BeforeEach

@BeforeEach
public void setup() {
    MockitoAnnotations.initMocks(this);
}

★★★의 JUnit5수입하다

import org.junit.runner.RunWith
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)

다음 중 하나:
Scala를 사용하고 있는 경우, 그 때,any가치 클래스에서는 도움이 되지 않는 NPE를 얻을 수 있습니다.

소정의case class ValueClass(value: Int) extends AnyVal 「」입니다.ValueClass(anyInt)any[ValueClass]

when(mock.someMethod(ValueClass(anyInt))).thenAnswer {
   ...
   val v  = ValueClass(invocation.getArguments()(0).asInstanceOf[Int])
   ...
}

이 다른 SO 질문은 좀 더 구체적이지만, 가치 클래스에 관한 문제인지 모를 때는 놓칠 수 있습니다.

주석 필드를 초기화하려면 MockitoAnnotations.initMocks(이) 메서드를 호출해야 합니다.

   @Before public void initMocks() {
       MockitoAnnotations.initMocks(this);
   }

자세한 내용은 문서를 참조하십시오.

JUnit 5의 경우 테스트 클래스에 주석을 달아야 합니다.

@ExtendWith(MockitoExtension.class)

Import:

import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;

이 추가 기능으로 문제가 해결되었습니다.

또 다른 공통점은 메서드 서명이 실수로 '최종'으로 선언된다는 것입니다.

를 Checkstyle로 할 수 .final.

예: OP의 예:

object.method()

「 」가 되어 것을 확인합니다.method() 않습니다.final:

public final Object method() {
}

Mockito는 최종 방법을 조롱할 수 없으며, 이는 랩된 NPE로 표시됩니다.

Suppressed: org.mockito.exceptions.misusing.InvalidUseOfMatchersException:

에러 메시지에는, 다음과 같은 내용이 포함되어 있습니다.

Also, this error might show up because you use argument matchers with methods that cannot be mocked.
Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
Mocking methods declared on non-public parent classes is not supported.

위의 답변 중 어느 것도 나에게 도움이 되지 않았다.왜 자바에서는 코드가 동작하지만 코틀린에서는 동작하지 않는지 이해하려고 애썼다.

그리고실타래에서 알아냈죠

의 기능을 .openpe n n 、 NPE 、 NPE n n가 n n n n n 。

open이치노

컴파일러의 "all-open" 플러그인을 사용하는 것이 좋습니다.

Kotlin은 기본적으로 클래스와 그 멤버들을 최종 등록하기 때문에 Spring AOP와 같은 클래스를 오픈해야 하는 프레임워크와 라이브러리를 사용하는 것이 불편합니다.all-open컴파일러 플러그인은 Kotlin을 이러한 프레임워크의 요건에 적응시키고 특정 주석으로 주석을 단 클래스와 명시적인 open 키워드 없이 멤버를 엽니다.

저 같은 경우에는 그 모의고사를 찌르고 있었기 때문에@BeforeAll★★★★★★ 。

MockitoExtension.@BeforeAll.

public class MockitoExtension implements BeforeEachCallback, AfterEachCallback, ParameterResolver

스텁은 테스트 방법 안에서 움직였어!!

경우에는 가 '를 만들었습니다.org.junit.jupiter.api.TestImport 신 ( ( Junit 5 )가 아닌 (5 )org.junit.Test이 되어 가 되어 있는 것 같습니다, 및 (Junit4)인 을 확인해 주세요.

저 같은 경우에는 덧셈을 먼저 놓쳤어요.

PowerMockito.spy(ClassWhichNeedToBeStaticMocked.class);

따라서 이러한 오류를 보는 사람에게 도움이 될 수 있습니다.

java.lang.NullPointerException
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.addAnswersForStubbing(PowerMockitoStubberImpl.java:67)
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:42)
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:112)
@RunWith(MockitoJUnitRunner.class) //(OR) PowerMockRunner.class

@PrepareForTest({UpdateUtil.class,Log.class,SharedPreferences.class,SharedPreferences.Editor.class})
public class InstallationTest extends TestCase{

@Mock
Context mockContext;
@Mock
SharedPreferences mSharedPreferences;
@Mock
SharedPreferences.Editor mSharedPreferenceEdtor;

@Before
public void setUp() throws Exception
{
//        mockContext = Mockito.mock(Context.class);
//        mSharedPreferences = Mockito.mock(SharedPreferences.class);
//        mSharedPreferenceEdtor = Mockito.mock(SharedPreferences.Editor.class);
    when(mockContext.getSharedPreferences(Mockito.anyString(),Mockito.anyInt())).thenReturn(mSharedPreferences);
    when(mSharedPreferences.edit()).thenReturn(mSharedPreferenceEdtor);
    when(mSharedPreferenceEdtor.remove(Mockito.anyString())).thenReturn(mSharedPreferenceEdtor);
    when(mSharedPreferenceEdtor.putString(Mockito.anyString(),Mockito.anyString())).thenReturn(mSharedPreferenceEdtor);
}

@Test
public void deletePreferencesTest() throws Exception {

 }
}

붙은 필요한 것은 아닙니다.{ 의 、 위 、 all 、 all 。mockContext = Mockito.mock(Context.class);@Mock Annotation을 사용하여Context mockContext;

@Mock 
Context mockContext; 

, @RunWith(Mockito)를 사용하면 동작합니다.JUnitRunner.class)만.Mockito에 따라 @Mock 또는 Mock(Context.class)을 사용하여 모의 객체를 만들 수 있습니다.

나는 Nullpointer를 얻었다.예외는 @RunWith(PowerMockRunner.class)가 아닌 @RunWith(Mockito)로 변경되어 있습니다.JUnitRunner.class)는 정상적으로 동작합니다.

음, 제 경우에는 잘못된 주석 사용 때문입니다.하고 Junit 4를 하였습니다.@BeforeEach@Before초기화 중.

changed changed changed changed changed changed 로 바꿨어요.@Before매력적으로 작용합니다.

제, in, for, 못, 못, 입, 입, for, for, in, in, in, in, in, in, in, 에 대한when().

하였습니다.import static reactor.core.publisher.Mono.when우연히

여기가 구글이 날 데려간 곳이야NullPointerException5를 했지만 Junit 5를 사용하고 .@ExtendWith(MockitoExtension.class)제 메이븐 프로젝트에서요

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★maven-surefire-plugin의 'pom.xml'이라는 뜻의 'pom.xml'이 요.@ExtendWith실사아아무!

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.22.1</version>
    </plugin>
    ...

에드 웹의 답변이 내 경우에 도움이 되었다.대신, 추가도 시도해 볼 수 있습니다.

  @Rule public Mocks mocks = new Mocks(this);

그렇다면@RunWith(JUnit4.class).

나는 이 대답들 중 어느 것도 통하지 않았다.이 답변으로는 OP의 문제를 해결할 수 없지만, 이 게시물만 이 문제에 대해 구글에서 확인할 수 있기 때문에 여기에서 답변을 공유합니다.

안드로이드 유닛 테스트를 작성하다가 이 문제를 알게 되었습니다.가 연장된 였습니다.AppCompatActivityActivity이 문제를 해결하기 위해, 저는 그냥 이 문제를AppCompatActivityActivity, 이 도움이입니다.이것이 모두에게 실행 가능한 해결책은 아닐 수도 있지만, 그 근본 원인을 아는 것이 누군가에게 도움이 되기를 바랍니다.

JUnit 5 상 ju 。은 '수업할 때'라는 주석이 달린 해야 합니다.@Mock an @BeforeEach

내 경우 @Test 주석을 잘못 가져온 것이 원인입니다.

다음 가져오기를 사용하고 있는지 확인하십시오.

import org.junit.jupiter.api.Test;

을 붙입니다.@ExtendWith(MockitoExtension.class).

내 경우 파라미터로 다른 메서드를 호출하는 테스트된 메서드:

Mockito.`when`(repository.getItems(prefs.getUser().id)).thenReturn(listOf())`

한편, 「 」는, 「 」, 「 」의 사이에repositoryprefs.getUser().id)NPE를 사용하다먼저 를 들어 를 들어 모수'를하다.

Mockito.`when`(prefs.getUser()).thenReturn(User(id = 1, name = "user"))`

놀림감으로 합니다.prefs이치노 송합니니다다

저는 "최종" 방식을 조롱하려고 했는데, 그게 문제였던 것 같습니다.

이것을 처리하는 올바른 방법은 인터페이스를 사용하여 그 인터페이스를 조롱하는 것이지만, 저는 최종적인 방법이 있는 라이브러리를 제어할 수 없었습니다.

모키토2는 모킹 파이널 메서드에 대응할 수 있습니다.프로젝트의 src/test/resources/mockito-extensions 디렉토리에 org.mockito라는 텍스트 파일을 추가합니다.플러그 인을 클릭합니다.MockMaker를 사용하여 한 줄의 텍스트를 추가합니다.

mock-maker-inline

그 후에는 마지막 방법을 조롱하는 것이 효과적일 것이다.

준잇을 사용하다에서 Maven/Gradle을 사용하도록 testRuntimeOnly 'junit5' 안 될 수도 안 될 수도 있어요.@RunWith할 수 사사 with with with with with with with with with with with with with since since with 로 대체되어 있기 @ExtendWithJunit 5 서 jun jun 。

이것은 OP의 원래 쿼리에 응답하지 않지만, NPE(Mockito null pointer exceptions)에 대해 다른 사용자를 돕기 위해 사용됩니다.

내 NPE는 내가 조롱했던 클래스로 테스트 대상 클래스를 명시적으로 설정하지 않았기 때문에 일어났다.따라서 테스트 대상 클래스는 필요한 종속성을 찾을 수 없었고 NPE가 생성되었습니다.나는 시험 대상 수업을 조롱하지 않는 경향이 있다(즉, 사용).new테스트용으로 네이티브클래스의 동작을 취득할 수 있도록 합니다.

나는 여전히 Junit 4를 내 통제 밖의 이유로 사용하고 있다.작업 예

클래스 언더 테스트

public class ClassUnderTest {
    private DependantClassOne dependantClassOne; 
    private DependantClassTwo dependantClassTwo;

    // remaining class, including setters
}

테스트 클래스

@RunWith(MockitoJUnitRunner.class)
public class Test {
    private ClassUnderTest classUnderTest;
    private DependantClassOne dependantClassOne;
    private DependantClassTwo dependantClassTwo;
 
    @Before
    public void setup() {
        dependantClassOne = mock(DependantClassOne.class);
        dependantClassTwo = mock(DependantClassTwo.class);
        classUnderTest = new ClassUnderTest();

        classUnderTest.setDependantClassOne(dependantClassOne); //added to prevent NPE
        classUnderTest.setDependantClassTwo(dependantClassTwo); //added to prevent NPE
    }

    // tests
}

내 경우, 내 Mockito 주석이 JUnit 버전과 일치하지 않습니다.

  1. 「」를 사용하고 @ExtendWith(MockitoExtension.class) 5: JUnit 5를 합니다.import org.junit.jupiter.api.Test;

  2. 「」를 사용하고 @RunWith(MockitoJUnitRunner.class) 4: JUnit 4를 합니다.import org.junit.Test;

요.@mock매퍼 선언에 기재되어 있습니다.

언급URL : https://stackoverflow.com/questions/33124153/mockito-nullpointerexception-when-stubbing-method