1

I would like to mock an object inside my class.

public class Controller{

   private StandardEmailSender sender = new StandardEmailSender();

    public void process() throws EmailException {
       // do some stuff
       sender.sendEmail(to, subject, body);
       // do some stuff
    }
 }

I would like to mock sender.sendEmail(to, subject, body);. I've spent time finding a solution but I'm stuck. I tried to mock directly the object StandardEmailSender like this :

@Mock
StandardEmailSender sender;

@Before
public void setUp() throws EmailException {
    MockitoAnnotations.initMocks(this);

    doNothing().when(sender).sendEmail(anyString(), anyString(), anyString());
}

@Test
public void test() throws EmailException {
    Controller controller= new Controller ();
    controller.process();

    //make some asserts
}

Would someone have a solution to my problem? Thanks!

0

2 Answers 2

3

You have two choices here:

  • make it possible for your test case to "manually" inject a (mocked) Sender object (for example by providing a constructor to set that field)
  • make use of Mockitos @InjectMocks annotation

A typical approach for option 1 is to use constructor telescoping, like this:

public class Controller {

 private final Sender sender;

 public Controller() { this(new StandardEmailSender()); }
 Controller(Sender sender) { this.sender = sender; }

By doing so, clients can still create a Controller instance without worrying about providing a sender, and your unit tests can use that package protected constructor to provide a mocked sender instance.

Sign up to request clarification or add additional context in comments.

1 Comment

@Kagelmacher Yes it does. But some people still dislike it: tedvinke.wordpress.com/2014/02/13/… ... and in case you find my answer sufficient, please dont forget about accepting at some point.
1

Use a form of dependency injection, for example:

public class Controller{
   private final EmailSender sender;

   Controller(EmailSender emailSender) {
       this.sender = Objects.requireNonNull(emailSender); 
   }

   public Controller() {
      this(new StandardEmailSender());
   }     
}

In your test:

@Test
public void test() throws EmailException {
    Controller controller= new Controller(mockedSender);
    controller.process();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.