Xavi Gómez Canals
Xavi Gómez Canals

Reputation: 155

Mockito and JUnit5 dependency testing problem

I have a class named Secret() and it has a associated class named Word(). This class Secret() handles a word that it receives from the Word() class through a method named getWord(). The problem is that I want to mock that getWord() method for test, but I can't. I should get a true assertion, but I get a false assertion

The Secret class:

public class Secret {

private String secret;
private Word word;

public Secret(){
    this.word = new Word();
    this.secret = word.getWord();
}

public String getSecret(){
    return this.secret;
}

//more methods... 
}

The Word class:

public class Word {

private String word;

public Word(){
    this.word = getFromFileRandom();
}

public String getFromFileRandom(){
    Random random = new Random();
    switch(random.nextInt(3)) {
        case 0:
            return "aabb";
        case 1:
            return "ccdd";
        case 2:
            return "eeff";
    }
    return "";
}

public String getWord(){
    return this.word;
}
}

...and the Test class

@ExtendWith(MockitoExtension.class)
public class Secretmethod Test {

@Mock
Word word;

@Test
public void test() throws IOException {
    String stringMocked = "secreta";
    when(this.word.getWord()).thenReturn(stringMocked);
    Secret secret = new Secret();
    assertThat(secret.getSecret(), is("secreta"));
}
}

Thanks community!

Upvotes: 0

Views: 92

Answers (3)

Alexzander Zharkov
Alexzander Zharkov

Reputation: 181

You can do Reflection, which is not usually good - but not really matters for testing:

String stringMocked = "secreta";
when(this.word.getWord()).thenReturn(stringMocked);
Secret secret = new Secret();

Field wordField = Secret.class.getDeclaredField("word");
wordField.setAccessible(true);
wordField.set(secret, this.word);

assertThat(secretB.getSecret(), is("secreta"));

Upvotes: 0

FrankelStein
FrankelStein

Reputation: 990

The Word instance in your Secret class is not the mocked one, your Secret class creates a new one each time it is instanciated.

Create a new constructor in your Secret class :

public Secret(Word word){
  this.word = word;
  this.secret = word.getWord();
}

And pass your mock in your test method :

@Test
public void test() throws IOException {
  String stringMocked = "secreta";
  when(this.word.getWord()).thenReturn(stringMocked);
  Secret secret = new Secret(this.word); // pass word mock here
  assertThat(secret.getSecret(), is("secreta"));
}

Upvotes: 2

Michael Katt
Michael Katt

Reputation: 643

You are creating a new Word instance within the Secret constructor which is not mocked. By annotating the Word member within the test class with @Mock Mockito creates a mocked instance of Word.

You have to bring the mocked Word instance into your Secret instance.e.g. via the constructor

public class Secret {

    private String secret;
    private Word word;

    public Secret(Word word){
          this.word =  word;
          this.secret = word.getWord();
     }
 ....

Upvotes: 1

Related Questions