Testowanie w Spock

0

Zastanawia mnie w w jaki sposób powiniem rozwiązać sytuację bo dostaję takiego errora :

org.spockframework.runtime.InvalidSpecException: Stub 'fileLinkRepository' matches the following required interaction:

12 * fileLinkRepository.findAll()   (0 invocations)

Remove the cardinality (e.g. '1 *'), or turn the stub into a mock.

W jaki sposób zamienić Stab na Mock w tym teście:

class FileExistTest extends Specification {

    FileLinkRepository fileLinkRepository = Stub()
    FileExist fileExist = new FileExist(fileLinkRepository)

def "should return given file name if file name is empty"() {
        given:
        String fileName = ""
        when:
        String actualName = fileExist.renameFileIfTheSameNameExists(fileName)
        then:
        actualName == fileName
    }

    def "should invoke findAll from repository only once"() {
        given:
        fileLinkRepository = Mock();

        when:
        fileExist.renameFileIfTheSameNameExists(_ as String)

        then:
        12 * fileLinkRepository.findAll()
    }

to rozwiazanie nie działa wyświetla:

Too few invocations for:

12 * fileLinkRepository.findAll()   (0 invocations)

Unmatched invocations (ordered by similarity):

None
0

Napisałeś test, który oczekuje, że metoda fileLinkRepository.findAll() zostanie wywołana 12 razy przy wywołaniu testowanej metody fileExist.renameFileIfTheSameNameExists(_ as String). Zamiast 12 wywołań było ich 0, więc test nie przeszedł. test działa, testowany kod nie.

0

Tak wygląda klasa i tam jest wywołanie metody findAll

public class FileExist {

    private FileLinkRepository fileLinkRepository;

    public FileExist(FileLinkRepository fileLinkRepository) {
        this.fileLinkRepository = fileLinkRepository;
    }

    public String renameFileIfTheSameNameExists(String fileName) {

        List<FileLink> fileLinks = fileLinkRepository.findAll();
        String extension = StringUtils.getFilenameExtension(fileName);

        boolean isTheSameNameExists = fileLinks.stream()
                .anyMatch(link -> link.getName().equals(fileName));

        int i = 1;
        while (isTheSameNameExists) {
            String newFileName =
                    fileName.substring(0, fileName.length() - extension.length() - 1) + "(" + i + ")." + extension;

            isTheSameNameExists = fileLinks.stream()
                    .anyMatch(link -> link.getName().equals(newFileName));

            if (!isTheSameNameExists) {
                return newFileName;
            }

            i++;
        }

        return fileName;
    }

}

0

Najpierw definiujesz

FileLinkRepository fileLinkRepository = Stub()
FileExist fileExist = new FileExist(fileLinkRepository)

a później nadpisujesz referencję w teście

fileLinkRepository = Mock();

fileExist nie ma w sobie nadpisanego Mocka (bo referencja w argumencie jest przekazywana przez wartość) i się nie nagrywa.

Poza tym to:

fileExist.renameFileIfTheSameNameExists(_ as String)

nie jest dobre. Rzutujesz w ten sposób _ na String "_". _ używasz w then, jeśli nie interesuje Cię, z jaką wartością argumentu wywołała się weryfikowana metoda. W when to raczej podajesz coś typu "dummy-string". Na koniec, opieranie testu tylko na nagrywaniu mocka jest raczej oznaką bad design kodu.

0

fileExist nie ma w sobie nadpisanego Mocka (bo referencja w argumencie jest przekazywana przez wartość) i się nie nagrywa.

Nie bardzo rozumiem. Mógłbyś pokazać jak to powinno być zapisane ?

2
public class SomeService {

    private Sorter sorter;
    private Random random = new Random();

    public SomeService(Sorter sorter) {
        this.sorter = sorter;
    }

    public List<Integer> gimmeSomeSortedInts(int count) {
        List<Integer> ints = random.ints().boxed().limit(count).collect(Collectors.toList());
        return sorter.sort(ints);
    }
}
public class Sorter {
    public List<Integer> sort(List<Integer> intList) {
        Collections.sort(intList);
        return intList;
    }
}
class SomeServiceSpec extends Specification {

    Sorter sorter = Mock()

    @Subject
    SomeService service = new SomeService(sorter)

    def "This is a poor test"() {
        when:
        service.gimmeSomeSortedInts(10)

        then:
        1 * sorter.sort(_)
    }

    def "This does not make any sense"() {
        given:
        sorter = Mock() // oh shiet! I have overriden my mock...

        when:
        service.gimmeSomeSortedInts(10)

        then:
        1 * sorter.sort(_) // ... and I verify here the old one :(
    }
    def "should return list of 10 ints"() {
        given:
        def intsCount = 10
        sorter.sort(_) >> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

        when:
        def result = service.gimmeSomeSortedInts(intsCount)

        then:
        result.size() == 10
    }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1