条件在 Junit5 和 Mockito 中失败

Condition fails in Junit5 & Mockito

我正在尝试为我的应用程序编写测试用例,但即使提供了我所知道的预期内容,我也无法通过条件。

这是我的测试class。

@ExtendWith(MockitoExtension.class)
class AppConfigTest {

  @Mock
  @TempDir
  File mockedFile;

  @InjectMocks
  private AppConfig appConfig;

  @Test
  void getData() throws Exception {
    File f = new File("f");
    File[] files = {f};

    lenient().when(mockedFile.listFiles()).thenReturn(files);
    lenient().when(mockedFile.isFile()).thenReturn(true);
    assertNotNull(appConfig.getData());
  }
}

我的实现。测试不会超过 if 条件。测试不覆盖条件之后的代码,因为它始终为真。我需要我的测试覆盖最后一行的 keyMap()。

  private Map<String, String> getData() {
    File[] files = new File(APP_CONST.DIRECTORY).listFiles();
    if (null == files) { // not turning FALSE even after providing mocked "files" array 
      return Collections.emptyMap();
    }
    List<String> keysList = getKeyList(files);
    return keyMap(APP_CONST.DIRECTORY, keysList);
  }

谁能告诉我如何更正这个问题?使用 SpringBoot/JUnit 5

我们在评论中对此进行了讨论,但无论如何,我想举个例子更好。

解决此问题的一种方法是确保存在相同的文件夹。在测试设置中,您可以简单地创建它。

@Before
public void setUp() {
   new File(APP_CONST.DIRECTORY).mkdirs();
}

现在在实现中访问时会有一个目录。也可以在test里面往目录里面添加文件,这样就不空了。

虽然这可行,但在设置和清理方面存在一些问题。更好的方法是从实现本身中抽象出来,并为它使用某种提供程序。

一个建议是创建一个接口,其中真正的实现 returns 真正的文件夹,在测试中你可以模拟它。

public interface DirectoryProvider {
   public File someDirectory();
}

public class RealDirectoryProvider implements DirectoryProvider {
   @Override
   public File someDirectory() {
     return new File(APP_CONST.DIRECTORY);
   }
}

您现在可以使 getData class 依赖于此抽象。你没有给我们 class 名字,所以不要注意那部分:

public class Data {
   private final DirectoryProvider directoryProvider;

   public Data(DirectoryProvider directoryProvider) {
     this.directoryProvider = directoryProvider;
   }

   private Map<String, String> getData() {
     File[] files = directoryProvider.someDirectory().listFiles();
     if (null == files) { 
       return Collections.emptyMap();
     }
     List<String> keysList = getKeyList(files);
     return keyMap(APP_CONST.DIRECTORY, keysList);
   }
}

现在在测试期间你可以注入你模拟的 directory/temp 目录。

@ExtendWith(MockitoExtension.class)
class AppConfigTest {
  @TempDir
  File mockedFile;

  @Mock
  DirectoryProvider directoryProvider;

  @InjectMocks
  private AppConfig appConfig;

  @Test
  void getData() throws Exception {
    lenient().when(directoryProvider.someDirectory()).thenReturn(mockedFile);

    assertNotNull(appConfig.getData());
  }
}

如果需要,您也可以将文件添加到临时目录。然而,这应该足以通过我认为的 if