当前位置: 首页 > 知识库问答 >
问题:

单元测试我无法向LiveData NullPointerException添加观察者

张献
2023-03-14

为什么我会得到nullPointerException尽管我删除了observer并使用了mLiveData.getValue()和assertNotNull(mLiveData)它工作得很好?

@RunWith(PowerMockRunner.class)
public class LoginRepositoryTest {

   //Data
   LoginRepository loginRepository;


   @Rule
   InstantTaskExecutorRule rule = new InstantTaskExecutorRule();


   @Mock
   AppExecutors appExecutors;
   @Mock
   LoginService loginService;
   @Mock
   Observer<Resource<Session>> loginObserver;
   @Mock
   ApiResponse<Session> loginResponse;
   @Mock
   ArgumentCaptor<Resource<Session>> resultLDCaptor;
   @Before
   public void setUp(){
       MockitoAnnotations.initMocks(this);
       RxAndroidPlugins.setInitMainThreadSchedulerHandler(scheduler -> Schedulers.trampoline());
       loginRepository=spy(new LoginRepository(appExecutors,loginService));
   }

   @Test
   public void testLoginSuccess(){


       //Prepare Login service
       MutableLiveData<ApiResponse<Session>> serviceLD=spy(new MutableLiveData<>());
       when(loginService.login(mock(RequestBody.class))).thenReturn(serviceLD);

       //Perform Login
       loginRepository.login(mock(RequestBody.class)).observeForever(loginObserver);

       //capture any value
       verify(loginObserver).onChanged(resultLDCaptor.capture());

       //Now value must be Resource.Loading
       assertNotNull(resultLDCaptor.getValue());
       assertTrue(resultLDCaptor.getValue().isLoading());

       //Now return fake data from server
       when(loginResponse.isSuccessful()).thenReturn(true);
       loginResponse.data=mock(Session.class);
       serviceLD.postValue(loginResponse);

   }

和错误

 
java.lang.NullPointerException
    at android.arch.lifecycle.MediatorLiveData$Source.plug(MediatorLiveData.java:141)
    at android.arch.lifecycle.MediatorLiveData.onActive(MediatorLiveData.java:118)
    at android.arch.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:410)
    at android.arch.lifecycle.LiveData.observeForever(LiveData.java:207)
    at com.wimoapp.android.login.LoginRepositoryTest.testLoginSuccess(LoginRepositoryTest.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)
    at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:202)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:144)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:118)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:121)
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
    at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
 

共有1个答案

封锐藻
2023-03-14

确保MediatorLiveData观察到的任何活动数据都不为空:

myMediatorLiveData.addSource(repository.getLiveData(), ...);
                                        ^^^^^^^^^^^

在我的示例中,repository.getLiveData()返回null,因为repository被嘲弄。在您的测试中,您可以通过使用mockito轻松地返回一个实时数据实例,例如:

MutableLiveData<...> liveData = new MutableLiveData<>();    
when(repository.getLiveData()).thenReturn(liveData);
 类似资料:
  • 我试图运行Spring Cloud Sleuth并观察traceid,spantid oin日志。 我的配置如下,但当我调用requesti cnat时,会在日志中看到任何traceId或logId。 有人帮忙吗。谢谢 build.gradle Controller.java

  • 我正在单元测试Angular 12组件。组件在初始化时从服务中获取可观察的返回(参见下面的)。它被分配给一个主题,该主题通过管道显示在html模板中(参见下面的)。 AppComponent.ts 模板订阅

  • 问题内容: 我试图使用类向单元格中添加图像,但是我进入了它应该在单元格中显示图像的单元格中尝试的代码: 问题答案: 您需要在表格模型上进行覆盖,并使用返回该列。否则,渲染器将显示,因为默认列类类型为。请参见如何使用表:编辑器和渲染器。 例如

  • 学习角得到服务和组件和可观察性。 我正在尝试在我的演示应用程序中实现暗模式。该控件由一个服务完成,该服务根据浏览器默认值(如果找到)设置暗主题。 它在应用程序组件中初始化,以便以后在应用程序中放置控制开关。 暗模式从布尔值开始工作,因此为true或false。据我所知,使用一个可观察对象是不够的,因为我希望多个订阅者都以两种方式绑定到订阅,每种方式在服务中切换这些可观察对象。到目前为止,我很肯定这

  • 我想测试我的Spring应用程序。当我将@SpringBootTest添加到我的测试类中时,即使我等待了一个多小时,测试也会挂起并且不会开始!删除SpringBootTest注释会导致初始化@Value字段失败,并且我无法测试任何组件类。我的配置类代码: 我的测试类: 运行测试类时的堆栈跟踪: 当我运行该测试时,该测试处于挂起状态:

  • 问题内容: 什么是空指针异常(),什么原因导致它们? 可以使用哪些方法/工具确定原因,以阻止异常导致程序过早终止? 问题答案: 声明引用变量(即对象)时,实际上是在创建指向对象的指针。考虑以下代码,您在其中声明基本类型的变量: 在此示例中,变量是an ,Java会为您初始化它。在第二行为其分配值时,您的值将写入所指的存储位置。 但是,当您尝试声明引用 类型时 ,会发生一些不同的事情。采取以下代码: