How do I verify if I am calling a service with the right paramether, when I want to ignore the rest...











up vote
1
down vote

favorite
1












I have EmailService class which has method sendEmail(Person person, Location location); Location is enum - Location.EUROPE and Location.USA. Based on the location I choose different email template, that is I have private method inside EmailService:



 private String chooseEmailTemplate(Location location){
if(location.equals(Location.EUROPE))
return "templateEU";
return "templateUSA";
}


inside the sendEmail(Person person, Location location) I call chooseEmailTemplate(location) and select the right template string.



public void sendEmail(Person person, Location location) {
String name = person.getName();
String age = person.getAge();
....

String emailTemplate = chooseEmailTemplate(location);

String body = templateEngine.process(emailTemplate, content);
...
//do something else and send the email
}


templateEngine is injected @Qualifier private TemplateEngine templateEngine;



UPDATE:
Inside EmailService I have the following method:



public void setTemplateEngine(TemplateEngine templateEngine) {
this.templateEngine = templateEngine;
}


And I am injecting it the following way:



 @Autowired
@Qualifier("textTemplateEngine")
private TemplateEngine templateEngine;


Inside EmailServiceTest this used to be my setUp():



@Before
public void setup() {
ThymeleafConfig tc = new ThymeleafConfig();
templateEngine = tc.templateEngine();

MockitoAnnotations.initMocks(this);
emailService.setTemplateEngine(templateEngine);
}


Yes, I know that templateEngine is not a mock but an actual object, and hence the error on line verify(templateEngine).process("templateEU", any(Content.class));. But when I change it to a mock, I get NullpointerException.



End Of the Update



In my test, I want to test that when Location is Europe it will process templateEU and when location is USA it will process templateEU.



I tried the following:



@Test
public void shouldCallTemplateEngineWithEuropeTemplate(){
location = Location.EUROPE;

//throws null pointer exception
emailService.sendEmail(any(Person.class), location);

verify(templateEngine).process("templateEU", any(Content.class));
}


But it complains that I am mocking the Person parameter. At this particular test, I don't care which Person object I am sending, I only care about the Location enum.










share|improve this question
























  • You can't call a method with "any person". You need to call it with a specific person. Then, based on that specific person, you can check that process() has been called with eq("templateEU"), and with any() content.
    – JB Nizet
    Nov 22 at 16:59












  • argument matchers are used when arranging or asserting member calls. They are not used as arguments when exercising the member under test'
    – Nkosi
    Nov 22 at 17:03






  • 1




    The message tells exactly what the problem is. You can only verify if a method has been called with expected arguments on a mock, not on a regular object.
    – JB Nizet
    Nov 22 at 17:10















up vote
1
down vote

favorite
1












I have EmailService class which has method sendEmail(Person person, Location location); Location is enum - Location.EUROPE and Location.USA. Based on the location I choose different email template, that is I have private method inside EmailService:



 private String chooseEmailTemplate(Location location){
if(location.equals(Location.EUROPE))
return "templateEU";
return "templateUSA";
}


inside the sendEmail(Person person, Location location) I call chooseEmailTemplate(location) and select the right template string.



public void sendEmail(Person person, Location location) {
String name = person.getName();
String age = person.getAge();
....

String emailTemplate = chooseEmailTemplate(location);

String body = templateEngine.process(emailTemplate, content);
...
//do something else and send the email
}


templateEngine is injected @Qualifier private TemplateEngine templateEngine;



UPDATE:
Inside EmailService I have the following method:



public void setTemplateEngine(TemplateEngine templateEngine) {
this.templateEngine = templateEngine;
}


And I am injecting it the following way:



 @Autowired
@Qualifier("textTemplateEngine")
private TemplateEngine templateEngine;


Inside EmailServiceTest this used to be my setUp():



@Before
public void setup() {
ThymeleafConfig tc = new ThymeleafConfig();
templateEngine = tc.templateEngine();

MockitoAnnotations.initMocks(this);
emailService.setTemplateEngine(templateEngine);
}


Yes, I know that templateEngine is not a mock but an actual object, and hence the error on line verify(templateEngine).process("templateEU", any(Content.class));. But when I change it to a mock, I get NullpointerException.



End Of the Update



In my test, I want to test that when Location is Europe it will process templateEU and when location is USA it will process templateEU.



I tried the following:



@Test
public void shouldCallTemplateEngineWithEuropeTemplate(){
location = Location.EUROPE;

//throws null pointer exception
emailService.sendEmail(any(Person.class), location);

verify(templateEngine).process("templateEU", any(Content.class));
}


But it complains that I am mocking the Person parameter. At this particular test, I don't care which Person object I am sending, I only care about the Location enum.










share|improve this question
























  • You can't call a method with "any person". You need to call it with a specific person. Then, based on that specific person, you can check that process() has been called with eq("templateEU"), and with any() content.
    – JB Nizet
    Nov 22 at 16:59












  • argument matchers are used when arranging or asserting member calls. They are not used as arguments when exercising the member under test'
    – Nkosi
    Nov 22 at 17:03






  • 1




    The message tells exactly what the problem is. You can only verify if a method has been called with expected arguments on a mock, not on a regular object.
    – JB Nizet
    Nov 22 at 17:10













up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





I have EmailService class which has method sendEmail(Person person, Location location); Location is enum - Location.EUROPE and Location.USA. Based on the location I choose different email template, that is I have private method inside EmailService:



 private String chooseEmailTemplate(Location location){
if(location.equals(Location.EUROPE))
return "templateEU";
return "templateUSA";
}


inside the sendEmail(Person person, Location location) I call chooseEmailTemplate(location) and select the right template string.



public void sendEmail(Person person, Location location) {
String name = person.getName();
String age = person.getAge();
....

String emailTemplate = chooseEmailTemplate(location);

String body = templateEngine.process(emailTemplate, content);
...
//do something else and send the email
}


templateEngine is injected @Qualifier private TemplateEngine templateEngine;



UPDATE:
Inside EmailService I have the following method:



public void setTemplateEngine(TemplateEngine templateEngine) {
this.templateEngine = templateEngine;
}


And I am injecting it the following way:



 @Autowired
@Qualifier("textTemplateEngine")
private TemplateEngine templateEngine;


Inside EmailServiceTest this used to be my setUp():



@Before
public void setup() {
ThymeleafConfig tc = new ThymeleafConfig();
templateEngine = tc.templateEngine();

MockitoAnnotations.initMocks(this);
emailService.setTemplateEngine(templateEngine);
}


Yes, I know that templateEngine is not a mock but an actual object, and hence the error on line verify(templateEngine).process("templateEU", any(Content.class));. But when I change it to a mock, I get NullpointerException.



End Of the Update



In my test, I want to test that when Location is Europe it will process templateEU and when location is USA it will process templateEU.



I tried the following:



@Test
public void shouldCallTemplateEngineWithEuropeTemplate(){
location = Location.EUROPE;

//throws null pointer exception
emailService.sendEmail(any(Person.class), location);

verify(templateEngine).process("templateEU", any(Content.class));
}


But it complains that I am mocking the Person parameter. At this particular test, I don't care which Person object I am sending, I only care about the Location enum.










share|improve this question















I have EmailService class which has method sendEmail(Person person, Location location); Location is enum - Location.EUROPE and Location.USA. Based on the location I choose different email template, that is I have private method inside EmailService:



 private String chooseEmailTemplate(Location location){
if(location.equals(Location.EUROPE))
return "templateEU";
return "templateUSA";
}


inside the sendEmail(Person person, Location location) I call chooseEmailTemplate(location) and select the right template string.



public void sendEmail(Person person, Location location) {
String name = person.getName();
String age = person.getAge();
....

String emailTemplate = chooseEmailTemplate(location);

String body = templateEngine.process(emailTemplate, content);
...
//do something else and send the email
}


templateEngine is injected @Qualifier private TemplateEngine templateEngine;



UPDATE:
Inside EmailService I have the following method:



public void setTemplateEngine(TemplateEngine templateEngine) {
this.templateEngine = templateEngine;
}


And I am injecting it the following way:



 @Autowired
@Qualifier("textTemplateEngine")
private TemplateEngine templateEngine;


Inside EmailServiceTest this used to be my setUp():



@Before
public void setup() {
ThymeleafConfig tc = new ThymeleafConfig();
templateEngine = tc.templateEngine();

MockitoAnnotations.initMocks(this);
emailService.setTemplateEngine(templateEngine);
}


Yes, I know that templateEngine is not a mock but an actual object, and hence the error on line verify(templateEngine).process("templateEU", any(Content.class));. But when I change it to a mock, I get NullpointerException.



End Of the Update



In my test, I want to test that when Location is Europe it will process templateEU and when location is USA it will process templateEU.



I tried the following:



@Test
public void shouldCallTemplateEngineWithEuropeTemplate(){
location = Location.EUROPE;

//throws null pointer exception
emailService.sendEmail(any(Person.class), location);

verify(templateEngine).process("templateEU", any(Content.class));
}


But it complains that I am mocking the Person parameter. At this particular test, I don't care which Person object I am sending, I only care about the Location enum.







java unit-testing mocking mockito






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 at 17:23

























asked Nov 22 at 16:52









sammy333

4913822




4913822












  • You can't call a method with "any person". You need to call it with a specific person. Then, based on that specific person, you can check that process() has been called with eq("templateEU"), and with any() content.
    – JB Nizet
    Nov 22 at 16:59












  • argument matchers are used when arranging or asserting member calls. They are not used as arguments when exercising the member under test'
    – Nkosi
    Nov 22 at 17:03






  • 1




    The message tells exactly what the problem is. You can only verify if a method has been called with expected arguments on a mock, not on a regular object.
    – JB Nizet
    Nov 22 at 17:10


















  • You can't call a method with "any person". You need to call it with a specific person. Then, based on that specific person, you can check that process() has been called with eq("templateEU"), and with any() content.
    – JB Nizet
    Nov 22 at 16:59












  • argument matchers are used when arranging or asserting member calls. They are not used as arguments when exercising the member under test'
    – Nkosi
    Nov 22 at 17:03






  • 1




    The message tells exactly what the problem is. You can only verify if a method has been called with expected arguments on a mock, not on a regular object.
    – JB Nizet
    Nov 22 at 17:10
















You can't call a method with "any person". You need to call it with a specific person. Then, based on that specific person, you can check that process() has been called with eq("templateEU"), and with any() content.
– JB Nizet
Nov 22 at 16:59






You can't call a method with "any person". You need to call it with a specific person. Then, based on that specific person, you can check that process() has been called with eq("templateEU"), and with any() content.
– JB Nizet
Nov 22 at 16:59














argument matchers are used when arranging or asserting member calls. They are not used as arguments when exercising the member under test'
– Nkosi
Nov 22 at 17:03




argument matchers are used when arranging or asserting member calls. They are not used as arguments when exercising the member under test'
– Nkosi
Nov 22 at 17:03




1




1




The message tells exactly what the problem is. You can only verify if a method has been called with expected arguments on a mock, not on a regular object.
– JB Nizet
Nov 22 at 17:10




The message tells exactly what the problem is. You can only verify if a method has been called with expected arguments on a mock, not on a regular object.
– JB Nizet
Nov 22 at 17:10












1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










argument matchers are used when arranging or asserting member calls on mocked dependencies.



They are not used/passed as arguments when exercising the member under test and will actually pass the default value of the type, which in this case would be null. Hence the null reference exception when



String name = person.getName();


is called.



Instead, create an instance of the parameter and pass that to the subject under test.



//Arrange
location = Location.EUROPE;
Person person = new Person();

//Act
emailService.sendEmail(person, location);

//Assert
//...


or just mock the class and pass that instead to avoid null reference errors



//Arrange
location = Location.EUROPE;
Person person = mock(Person.class);

//Act
emailService.sendEmail(person, location);

//Assert
//...


making sure to setup any member calls on Person that would cause issues if not configured.



As for the template issue, you would should mock the template so that the unit test is truly an isolated test.



@Before
public void setup() {
templateEngine = mock(TemplateEngine.class); //Use a mock

MockitoAnnotations.initMocks(this);
emailService.setTemplateEngine(templateEngine);
}


And



verify(templateEngine).process("templateEU", any(Content.class));


behaves as intended.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435405%2fhow-do-i-verify-if-i-am-calling-a-service-with-the-right-paramether-when-i-want%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    argument matchers are used when arranging or asserting member calls on mocked dependencies.



    They are not used/passed as arguments when exercising the member under test and will actually pass the default value of the type, which in this case would be null. Hence the null reference exception when



    String name = person.getName();


    is called.



    Instead, create an instance of the parameter and pass that to the subject under test.



    //Arrange
    location = Location.EUROPE;
    Person person = new Person();

    //Act
    emailService.sendEmail(person, location);

    //Assert
    //...


    or just mock the class and pass that instead to avoid null reference errors



    //Arrange
    location = Location.EUROPE;
    Person person = mock(Person.class);

    //Act
    emailService.sendEmail(person, location);

    //Assert
    //...


    making sure to setup any member calls on Person that would cause issues if not configured.



    As for the template issue, you would should mock the template so that the unit test is truly an isolated test.



    @Before
    public void setup() {
    templateEngine = mock(TemplateEngine.class); //Use a mock

    MockitoAnnotations.initMocks(this);
    emailService.setTemplateEngine(templateEngine);
    }


    And



    verify(templateEngine).process("templateEU", any(Content.class));


    behaves as intended.






    share|improve this answer



























      up vote
      2
      down vote



      accepted










      argument matchers are used when arranging or asserting member calls on mocked dependencies.



      They are not used/passed as arguments when exercising the member under test and will actually pass the default value of the type, which in this case would be null. Hence the null reference exception when



      String name = person.getName();


      is called.



      Instead, create an instance of the parameter and pass that to the subject under test.



      //Arrange
      location = Location.EUROPE;
      Person person = new Person();

      //Act
      emailService.sendEmail(person, location);

      //Assert
      //...


      or just mock the class and pass that instead to avoid null reference errors



      //Arrange
      location = Location.EUROPE;
      Person person = mock(Person.class);

      //Act
      emailService.sendEmail(person, location);

      //Assert
      //...


      making sure to setup any member calls on Person that would cause issues if not configured.



      As for the template issue, you would should mock the template so that the unit test is truly an isolated test.



      @Before
      public void setup() {
      templateEngine = mock(TemplateEngine.class); //Use a mock

      MockitoAnnotations.initMocks(this);
      emailService.setTemplateEngine(templateEngine);
      }


      And



      verify(templateEngine).process("templateEU", any(Content.class));


      behaves as intended.






      share|improve this answer

























        up vote
        2
        down vote



        accepted







        up vote
        2
        down vote



        accepted






        argument matchers are used when arranging or asserting member calls on mocked dependencies.



        They are not used/passed as arguments when exercising the member under test and will actually pass the default value of the type, which in this case would be null. Hence the null reference exception when



        String name = person.getName();


        is called.



        Instead, create an instance of the parameter and pass that to the subject under test.



        //Arrange
        location = Location.EUROPE;
        Person person = new Person();

        //Act
        emailService.sendEmail(person, location);

        //Assert
        //...


        or just mock the class and pass that instead to avoid null reference errors



        //Arrange
        location = Location.EUROPE;
        Person person = mock(Person.class);

        //Act
        emailService.sendEmail(person, location);

        //Assert
        //...


        making sure to setup any member calls on Person that would cause issues if not configured.



        As for the template issue, you would should mock the template so that the unit test is truly an isolated test.



        @Before
        public void setup() {
        templateEngine = mock(TemplateEngine.class); //Use a mock

        MockitoAnnotations.initMocks(this);
        emailService.setTemplateEngine(templateEngine);
        }


        And



        verify(templateEngine).process("templateEU", any(Content.class));


        behaves as intended.






        share|improve this answer














        argument matchers are used when arranging or asserting member calls on mocked dependencies.



        They are not used/passed as arguments when exercising the member under test and will actually pass the default value of the type, which in this case would be null. Hence the null reference exception when



        String name = person.getName();


        is called.



        Instead, create an instance of the parameter and pass that to the subject under test.



        //Arrange
        location = Location.EUROPE;
        Person person = new Person();

        //Act
        emailService.sendEmail(person, location);

        //Assert
        //...


        or just mock the class and pass that instead to avoid null reference errors



        //Arrange
        location = Location.EUROPE;
        Person person = mock(Person.class);

        //Act
        emailService.sendEmail(person, location);

        //Assert
        //...


        making sure to setup any member calls on Person that would cause issues if not configured.



        As for the template issue, you would should mock the template so that the unit test is truly an isolated test.



        @Before
        public void setup() {
        templateEngine = mock(TemplateEngine.class); //Use a mock

        MockitoAnnotations.initMocks(this);
        emailService.setTemplateEngine(templateEngine);
        }


        And



        verify(templateEngine).process("templateEU", any(Content.class));


        behaves as intended.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 22 at 17:27

























        answered Nov 22 at 17:06









        Nkosi

        108k16113182




        108k16113182






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435405%2fhow-do-i-verify-if-i-am-calling-a-service-with-the-right-paramether-when-i-want%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            What visual should I use to simply compare current year value vs last year in Power BI desktop

            Alexandru Averescu

            Trompette piccolo