jeudi 24 septembre 2020

Groovy spock test isn't stubbing correctly -- receiving null

For some reason (I'm not very good with Spock and am new to mocking & stubbing) I can't get a particular method to stub with what I want.

I've shortened things down a bit, but basically I have a list of books returned from a search. Each book has a workId. There may be older or newer editions of the book, but they all have the same workId -- If a user chooses, they can grab all those other editions.

Preface


Class: Edition

class Edition {
    //some strings, ints, and booleans -- information about the edition
}

Class: EditionResults for grabbing additional editions of a single work

class EditionResults {
    List<Edition> editionsList
    String parentWorkId
}

And one final class: BulkEditions for packaging multiple works (10 books on a search result page)

class BulkEditions {
    List<EditionResults> bulkEditions
}

This controller is where I'm having trouble

@RequestMapping('/api')
class EditionsController {

    @Autowired
    private EditionsService editionsService

    private Logger logger = LoggerFactory.getLogger(EditionsController)

    @RequestMapping(value = '/bulkeditions', produces = 'application/json')
        ResponseEntity<BulkEditions> getBulkEditions(
                @RequestParam(value = 'workIds') Set<String> workIds
        ) throws Exception {
            BulkEditions newBulkEditions = new BulkEditions(bulkEditions: [])
            workIds.each { workId ->
                EditionResults editions = editionsService.searchEditions(workId)

                logger.info "EditionResults {}", editions
                if (editions?.editionsList) { newBulkEditions.bulkEditions << editions }
            }

            new ResponseEntity<BulkEditions>(newBulkEditions, HttpStatus.OK)
        }

particularly, i'm having trouble testing the true branch of editions?.editionsList -- for some reason I keep receiving null for editions


Here's what my test looks like (it always passes, but clover coverage is failing)

class EditionsControllerSpec extends Specification {

    private final EditionsService editionsService = Mock(EditionsService)
    private static final Set<String> WORK_ID_SET = '12345' as Set<String>
    private static final String SINGULAR_WORK_ID = '12345'

    @Subject
    private final EditionsController controller = new EditionsController(editionsService: editionsService)

    void 'test get bulk editions'() {
        given:
        EditionResults editionResults = Mock(EditionResults)
        Edition edition = GroovyMock(Edition) //it's a java class
        edition.isAvailable >> true
        //edition.bunchOfOtherProps >> randomValues

        editionResults.editionsList >> [edition]
        editionResults.parentWorkId >> SINGULAR_WORK_ID
    
        editionsService.searchEditions(SINGULAR_WORK_ID) >> editionResults

        when:
        ResponseEntity<BulkLocalEditions> response = controller.getBulkEditions(WORK_ID_SET)

        then:
        response
    }


My problem is this part:

editionsService.searchEditions(SINGULAR_WORK_ID) >> editionResults

I don't understand why I keep getting this back (from my logger)

[Test worker] INFO [EditionsController:100] [doCall] EditionResults ***null***

My understanding is that editionsService.searchEditions(SINGULAR_WORK_ID) >> editionResults is equivalent to saying "When we hit this searchEditions method, make its result editionResults" -- which we've already populated.... so how is it null?


I've tried being as detailed and clean as I can with the question, simplifying for brevity, but please let me know if there's any additional info needed -- and of course thanks in advance.

Also worth noting that it actually works on my local and everything comes back correctly -- it's just this clover coverage getting me

Aucun commentaire:

Enregistrer un commentaire