我有一个程序,可以为给定国家列表中的每个条目创建目录。
例如:如果传递一个阿尔巴尼亚,葡萄牙,比利时,以色列的列表,它将创建一个目录ABC(在其中创建阿尔巴尼亚和比利时的目录),PQR(在其中创建葡萄牙的目录),GHI(在其中以色列的目录)创建)。如果该程序再次与博茨瓦纳和波兰一起运行,它将删除目录ABC和PQR,然后重新创建它们。

我想编写一个测试来验证仅删除了目录ABC和PQR并且保留了目录GHI。该程序可以正常运行,但是现在我需要编写一个模拟测试,而且我不知道该怎么做。我是mockito的新手:/这是我的课程。

public class FileDeleter implements Deleter {

    public void deleteDirectories(List<GroupOfCountries> organizedCountries, String path) {
        List<String> listOfThreeLettersGroups = new ArrayList<String>();

        for (GroupOfCountries groupedCountries : organizedCountries) {
            listOfThreeLettersGroups.add(groupedCountries.getName()); //Here it's adding "ABC" and "PQR" to ArrayList because my countries are Albania, Belgium and Portugal.
        }

        for (String directoryToDelete : listOfThreeLettersGroups) {
            String pathOfGorupDirectory = (path + File.separator + directoryToDelete); //Here it's creating paths to ABC and PQR directories, for example /home/test/ABC
            File tempfile = createFile(pathOfGorupDirectory);
            deleteDirectory(tempfile);
        }
    }

    protected File createFile(String pathOfGorupDirectory) {
        return new File(pathOfGorupDirectory);
    }

    private boolean deleteDirectory(File dir) {
        if (dir.isDirectory()) {
            File[] children = dir.listFiles();
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDirectory(children[i]);
                if (!success) {
                    return false;
                }
            }
        }
        return dir.delete();
    }
}


这是我的测试。我尝试过这种方式,但是我不确定在这里我还能做些什么:/

@RunWith(MockitoJUnitRunner.class)
public class FileDeleterTest {

    @Mock
    private File file;

    @Mock
    private File childFile;

    private FileDeleter fileDeleter;

    @Before
    public void setUp() {
        fileDeleter = new FileDeleter(userInputs) {
            protected File createFile(String pathOfGorupDirectory) {
                return file;
            };
        };
    }

    @Test
    public void testMultipleGroupsReplace() {

        File[] fileChildrenEmpty = new File[0];
        File[] fileChildrenWithMockChild = new File[] { childFile };
        doReturn(true).doReturn(false).when(file).isDirectory();
        doReturn(fileChildrenWithMockChild).doReturn(fileChildrenEmpty).when(file).listFiles();
        String path = "somepath";

        List<GroupOfCountries> groupOfCountries = new ArrayList<GroupOfCountries>();
        List<Country> countries = new ArrayList<Country>();
        countries.add(new Country("Albania"));
        countries.add(new Country("Belgium"));
        GroupOfCountries firstGroup = new GroupOfCountries("ABC", countries);
        groupOfCountries.add(firstGroup);

        countries = new ArrayList<Country>();
        countries.add(new Country("Portugal"));
        GroupOfCountries secondGroup = new GroupOfCountries("PQR", countries);
        groupOfCountries.add(secondGroup);

        fileDeleter.deleteDirectories(groupOfCountries, path);

        verify(childFile, times(1)).delete();
    }
}

最佳答案

创建FileDeleter类的方式很难测试。我建议您将文件操作移至单独的类/接口,以便可以使用Mockito模拟其行为。你上课可能是这样的。

public class CountryDirectoryDeleter {

    private Deleter fileDeleter;

    public CountryDirectoryDeleter() {
        fileDeleter = new FileDeleter();
    }

    public void deleteDirectories(List<GroupOfCountries> organizedCountries, String path) {
        List<String> listOfThreeLettersGroups = new ArrayList<String>();

        for (GroupOfCountries groupedCountries : organizedCountries) {
            listOfThreeLettersGroups.add(groupedCountries.getName()); //Here it's adding "ABC" and "PQR" to ArrayList because my countries are Albania, Belgium and Portugal.
        }

        for (String directoryToDelete : listOfThreeLettersGroups) {
            String pathOfGorupDirectory = (path + File.separator + directoryToDelete); //Here it's creating paths to ABC and PQR directories, for example /home/test/ABC
            File tempfile = fileDeleter.createFile(pathOfGorupDirectory);
            fileDeleter.deleteDirectory(tempfile);
        }
    }


    public FileDeleter getFileDeleter() {
        return fileDeleter;
    }

    public void setFileDeleter(FileDeleter fileDeleter) {
        this.fileDeleter = fileDeleter;
    }
}


FileDeleter将如下所示:

public class FileDeleter implements Deleter {

    public File createFile(String pathOfGorupDirectory) {
        return new File(pathOfGorupDirectory);
    }

    public boolean deleteDirectory(File dir) {
        if (dir.isDirectory()) {
            File[] children = dir.listFiles();
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDirectory(children[i]);
                if (!success) {
                    return false;
                }
            }
        }
        return dir.delete();
    }
}


然后,在测试中,您可以将CountryDirectoryDe​​leter中的'fileDeleter'字段设置为模拟对象,并且在测试中,您可以验证使用正确的文件名调用了模拟对象的deleteDirectory()方法。

Mockito.verify(mockFileDeleter).when(deleteDirectory("directory name to verify"));

08-06 15:59