Come testare meglio questo metodo? Devo dividerlo?

0

Va bene, per favore considera il seguente metodo. Permettetemi innanzitutto di dirvi che i miei obiettivi del metodo è determinare se esistono risorse del file system. Questo vuol dire che si tratta di un sito aziendale interno in cui ci si aspetta che la directory di base sia già presente sul server installato e lo stesso con il parametro passato directory e nome file. L'utente finale dell'app Web avrà GIÀ messo in atto le risorse.

Ciò che questo metodo verifica è che tutto funzioni.

MA, come faccio a testarlo? Non voglio testare che le classi JAVA.NIO funzionino, so che lo faranno. Voglio testare che, dato un insieme di input, i miei comportamenti sono quelli che penso che siano.

Come faresti questo?

@Component
public class FilePathTestService {

    @Value("${userlists.basedirectory}")
    private String userListDirectory;

    public FilePathTestResult testFilePath(FilePathTestRequest filePathTestRequest) {

            if (StringUtils.isBlank(userListDirectory))         
            {
                return  (new FilePathTestResult(
                    false, 
                    "ERROR: Base userListDirectory is Blank/Null"));
            }

            try {
                Path pathToDirectory = Paths.get(
                    userListDirectory, 
                    filePathTestRequest.getPathName());

                if (!Files.isDirectory(pathToDirectory))
                {
                    return  (new FilePathTestResult(
                        false, 
                        "ERROR: Directory could not be found for this path."));
                }

                Path pathToFile = Paths.get(
                    userListDirectory, 
                    filePathTestRequest.getPathName(), 
                    filePathTestRequest.getFileName());

                if (Files.notExists(pathToFile))
                {
                    return  (new FilePathTestResult(
                        false, 
                        "ERROR: File could not be found, but directory was found."));
                }   
                else {
                    File fileInfo = pathToFile.toFile();
                    FilePathTestResult result = new FilePathTestResult(true);
                    result.setModifyDate(LocalDateTime.ofInstant(Instant.ofEpochMilli(
                        fileInfo.lastModified()), 
                        ZoneId.systemDefault()));
                    return (result);
                }

            } catch (InvalidPathException e) {  
                return  (new FilePathTestResult(
                    false, 
                    "ERROR: This path string cannot be converted to a Path"));
        }                       
    }   
}
    
posta Paul Duer 15.09.2016 - 15:07
fonte

2 risposte

1

Sembra piuttosto semplice, non c'è bisogno di dividerlo se non ti piace. Fornire un modo per impostare userListDirectory direttamente, senza la necessità di una configurazione Spring (ad esempio, aggiungere un costruttore per FilePathTestService in cui è possibile passare userListDirectory come parametro).

Quindi puoi facilmente scrivere test con combinazioni diverse di userListDirectory e filePathTestRequest dati come input, dove passi i nomi di file e cartelle esistenti, file non esistenti in cartelle esistenti o una cartella non esistente (di naturalmente, dovresti fornire alcuni file e cartelle come dati di test per questo scopo). Ogni test può convalidare se l'oggetto FilePathTestResult restituito contiene ciò che ci si aspetta che contenga.

Puoi rendere il test un po 'più robusto se estendi l'oggetto FilePathTestResult di una macchina leggibile enum che indica il tipo esatto di errore. In questo modo, puoi affermare che la funzione restituisce il tipo previsto, invece di confrontare i risultati con la stringa di errore restituita. I messaggi di errore potrebbero essere soggetti a modifiche in futuro, i codici di errore non tendono a cambiare così frequentemente.

    
risposta data 15.09.2016 - 15:24
fonte
0

La risposta di Doc è molto buona (soprattutto essendo in grado di impostare le cose direttamente) e funzionerà bene se si desidera toccare il filesystem per i test. Non c'è niente di sbagliato nel farlo, ma alcune persone preferiscono non farlo perché non considerano questa cosa più da non essere più disponibile (ci sono opinioni diverse sul fatto che l'unittests debba o meno toccare database, filesystem e simili che ho vinto entrare in). Tieni a mente che il test con un file system effettivo comporterà alcune penalità rispetto alla velocità con cui eseguirai i test.

In alternativa, l'approccio che prendo a queste cose è il wrapping di tutte le operazioni di I / O in una semplice classe che implementa un'interfaccia (ad esempio FileSystem o qualche variazione). Questa classe passa semplicemente alle operazioni File esistenti e non contiene alcuna logica. Ciò mi consente di mettere a punto l'interfaccia FileSystem che consente l'univest che non tocca il filesystem.

La classe wrapping non viene testata tramite un unittest perché non contiene alcuna logica effettiva (è un semplice pass-through) e un certo grado di testing su di esso viene eseguito comunque dai test di integrazione.

    
risposta data 15.09.2016 - 16:00
fonte

Leggi altre domande sui tag