Search code examples
groovyspock

Spock UnitTest, Too few invocations, but exact same invocation in "Unmatched invocations" list


I am writing a Unit Test for some Code of mine that calculates Time. I'm using SQL.date as an input and convert it to Calendar for the calculation. (Yes I know Joda would be better).

My test is as following:

def objectOrgUnit = Stub(ConOrgUnit)

def notification

def setup(){
    objectOrgUnit = Stub(ConOrgUnit) {
        getLogicalName() >> "Multimedia"
    }
}

def "CreateNotification creates Notification with correctly caluclated dates"() {
    given:
    def date = new java.sql.Date(2020-1900,4,1)

    def not = new NotificationGenerator()
    def contract = GroovyMock(GenericBean) {
        getCtrInsuranceDateToDat() >> date
    }
    def vocs = GroovyStub(ControlledVocabularyAccess) {
        getNodesByInstanceAndName('TasStatusVgr', 'open') >> [Stub(ControlledVocabularyNode)]
        getNodesByInstanceAndName('TasTypeVgr', 'TYPE') >> [Stub(ControlledVocabularyNode)]
    }

    def newNotification = GroovyMock(GenericBean) {
        getTasContract02Ref() >> GroovyMock(GenericBean)
        getTasSendEmailGrp() >> GroovyMock(GenericBean)
    }

    def dataAccess = GroovyStub(DataAccess) {
        createObject("Task") >> newNotification
    }
    def orgUnitAdminService = Stub(OrgUnitAdminServiceAccess) {
        readUsingLogicalName("org") >> objectOrgUnit
    }
    not.metaClass.vocs = vocs
    not.metaClass.dataAccess = dataAccess
    not.metaClass.orgUnitAdminService = orgUnitAdminService
    when:
    notification = not.createNotification(contract, 2, "REASON", "TYPE", "[email protected]", "org")
    then:
    1 * newNotification.setTasDeadlineDat(2020-02-01)
    1 * newNotification.setTasDeadlineToDat(2020-02-01)
}

when run, it gives me the error:

1 * newNotification.setTasDeadlineDat(2020-02-01)   (0 invocations)

Unmatched invocations (ordered by similarity):

1 * newNotification.setTasDeadlineDat(2020-02-01)

So it looks like it would be correct? I also tried testing for "date" which doesn't work either.

The code itself is this (partly):

    Calendar c = Calendar.getInstance()
    c.setTime(contract.CtrInsuranceDateToDat)
    c.add(Calendar.MONTH, -1 * (months + 1))
    taskNotification.TasDeadlineDat = new java.sql.Date(c.getTime().getTime())
    taskNotification.TasDeadlineToDat = new java.sql.Date(c.getTime().getTime())

Solution

  • Okay, I cannot run your test, but I think I spotted it:

    then:
    1 * newNotification.setTasDeadlineDat(2020-02-01)
    1 * newNotification.setTasDeadlineToDat(2020-02-01)
    

    2020-02-01 is just a subtraction 2020 - 2 - 1 or 2017, not a date, neither a simple Java date nor an SQL date (which is a subclass of the Java date, so be careful).

    I think what you rather want is something like:

    given:
    def expectedDate = new SimpleDateFormat("yyyy-MM-dd").parse("2020-02-01")
    
    // ...
    
    then:
    1 * newNotification.setTasDeadlineDat(expectedDate)
    1 * newNotification.setTasDeadlineToDat(expectedDate)
    

    Now you are really comparing dates. It works for comparing java.sql.Date and java.util.Date because the latter does not override the equals(..) method of the former.