Home > Back-end >  How to mock/spy Jenkins.insatance using spock
How to mock/spy Jenkins.insatance using spock

Time:11-27

I have this code in my pipeline, now I want to add unit test for it using spock framework, the issue is how to mock or spy Jenkins.instance and all chaining methods.

 String deployPipeline = "Deploy/${projectID}/deploy-to-prod"
 def lastRelease = Jenkins.instance.getItemByFullName(deployPipeline).getLastSuccessfulBuild()

 String lastDeployedVersion = lastRelease.getBadgeActions().findResult {
    String text = it.getText()
    if (text != null && text.matches(/^Version\=/) != null) {
        return text.find(/\d \.\d \.\d /)
    }
 }

CodePudding user response:

You don't have to mock Jenkins.instance but Run for the mock object of which you define which List<BuildBadgeAction> should be returned if its getBadgeActions() is called.

You don't want to test Jenkins' call stack but what your code does with items of a list, do you?

So, you have to do something like (in JUnit 5/Mockito semi-pseudocode, I don't use Spock, but I think you get the idea):

class YourClassTest {

  @InjectMocks 
  YourClass yourClass = new YourClass();

  @Mock
  Run run;


  @Test
  testYourMethod() {

    List<BuildBadgeAction> list = new ArrayList<>();
    list.add( new ... BuildBadgeAction implementation ... );
    list.add( new ... BuildBadgeAction implementation ... );
    ... 

    when( run.getBadgeActions() ).thenReturn( list );

    assertEquals( "...", yourClass.getLastDeployedVersion() ); 

  }

}

For @InjectMocks to work you have to have a declaration Run run; in YourClass (or a constructor YourClass(Run run) or a setter setRun(Run run)).

And, BTW, none of the implementations of the interface BuildBadgeAction has a getText() method.

CodePudding user response:

I ended up something like this

        BuildBadgeAction badge1Mock = GroovyMock(BuildBadgeAction) {
            _.getText() >> "Version= 1.2.3"
            _.getDisplayName() >> "Version= 1.2.3"
        }

        BuildBadgeAction badge2Mock = GroovyMock(BuildBadgeAction) {
            _.getText() >> "badge-2"
            _.getDisplayName() >> "badge-2"
        }

        def runMock = GroovyMock(Run) {
            _.getBadgeActions() >> {
                return [badge1Mock, badge2Mock]
            }
        }

        Item itemMock = GroovyMock(Item) {
            _.getFullName() >> "job-1"
            _.getLastSuccessfulBuild() >> { 
                runMock
            }
        }        

        def jenkinsInstanceMock = GroovyMock(Jenkins) {
            _.getItemByFullName(_) >> { String fullName ->
            itemMock
        }

        GroovySpy(Jenkins, global: true, useObjenesis: true) {
            _.getInstance() >> jenkinsInstanceMock
        }


  • Related