【问题标题】:Trying to mock a service but I get NullPointerException (JUNIT/MOCKITO)试图模拟服务,但我得到 NullPointerException (JUNIT/MOCKITO)
【发布时间】:2020-08-03 21:06:32
【问题描述】:

我是 Junit 和 Mockito 单元测试的新手。我需要对方法“processFiles(final File folder)”进行单元测试

由于我在这个名为 myService.isFileOk(data) 的方法中调用了另一个服务,我想我需要模拟这个服务以使其返回 true。

但是当我运行我的测试时,我得到一个空指针异常。

这是 processFiles 方法的部分代码:

  @EJB
  private transient MyService myService;

  public void processFiles(final File folder)
  {
     
      File[] fileNames = folder.listFiles();
      List<String> lines = new ArrayList<>();
      boolean isFirstFile = true;
      try
      {
          for (File file : fileNames)
          {
                  List<String> l = readContent(file, isFirstFile);
                  l.forEach(i -> lines.add(i));
                  isFirstFile = false;     
          }

          String[] data = lines.get(0).trim().split(";");
          if (!this.myservice.isFileOk(data))
          {
            // ...
          }
          else
          {
              // ...
          }
      }
      catch (IOException e)
      {
          e.printStackTrace();
      }
  }

这就是我尝试测试我的 processFile 方法的方式

    @Mock
    public MyService myService ;

    @Rule
    public TemporaryFolder temporaryFolder = new TemporaryFolder();


    @Test
    public void testWrite2() throws IOException {

        final File tempFile1 = temporaryFolder.newFile("tempFile.txt");
        final File tempFile2 = temporaryFolder.newFile("tempFile2.txt");

        String[] data = {"a", "b" , "c" , "d"} ;
        this.myService = new MyService();


       MyService myService = Mockito.mock(MyService.class);
 
       when(myService.isFileOk(data)).thenReturn(true);


//... myclass.processFiles(file);
    }

你知道我应该如何继续模拟 isFileOk 吗?非常感谢您的帮助

【问题讨论】:

  • 持有@EJB私有瞬态MyService myService的类的名称是什么;
  • 如何初始化 myclass 实例?我猜这是持有 myService 的 myclass
  • 同时删除“this.myService = new MyService();”如果你要模拟它。
  • 是的,MyClass 持有 @EJB 私有瞬态 MyService myService;
  • 然后我像这样初始化它:@Mock ListFilesService listFilesService;

标签: java junit mockito junit4


【解决方案1】:

您遇到的问题是您试图模拟 @EJB,它将由您的容器服务在实际运行时注入。

但是,在您的测试中,您没有使用容器服务,因此该服务不会被注入并在您的类实例中保持为空。

本质上,您正在寻找 Spring 的“@RunWith(SpringRunner.class)”注解的 EJB 等价物,它在您的测试用例执行中执行注入。

据我所知,EJB 没有这个,但我有一段时间没有使用它,所以我可能是错的。如果它确实没有,接下来你可以做的就是使用反射来强制它。

【讨论】:

    【解决方案2】:

    您需要做的是将模拟传递给持有实例的类并使用匹配器:

    https://www.javadoc.io/doc/org.mockito/mockito-core/1.9.5/org/mockito/Matchers.html

    when(myService.isFileOk(eq(data))).thenReturn(true);
    

    您还定义了两次 MyService。一次是全局的,一次是在方法内部的。也许您应该考虑删除两者之一。

    您可以使用反射来设置 private transient MyService myService; in MyClass

    Field myServiceField = myclass.getClass().getDeclaredField("myService");
    myServiceField.setAccessible(true);
    f1.set(myClass, mock);
    

    然后调用:

    myclass.processFiles(file);
    

    现在你的模拟应该被初始化了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-29
      • 2020-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多