【问题标题】:Mockito and JUnit5 dependency testing problemMockito 和 JUnit5 依赖测试问题
【发布时间】:2021-08-10 12:26:02
【问题描述】:

我有一个名为 Secret() 的类,它有一个名为 Word() 的关联类。此类 Secret() 处理它通过名为 getWord() 的方法从 Word() 类接收到的单词。 问题是我想模拟该 getWord() 方法进行测试,但我不能。我应该得到一个正确的断言,但我得到了一个错误的断言

秘密类:

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... 
}

单词类:

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;
}
}

...和测试类

@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"));
}
}

感谢社区!

【问题讨论】:

  • 尝试对 Word 类使用 powermockito.whenNew()
  • 感谢回答,请问powermockito.whenNew()如何使用?我将通过谷歌调查
  • PowerMockito.whenNew(Word.class).withAnyArguments().thenReturn(word);注意:这里的“单词”是你的模拟对象。
  • 非常感谢 DKS!我试试看告诉你!
  • 嗨 DKS,我无法尝试使用 powermockito,但感谢您的评论!

标签: java unit-testing mockito junit5


【解决方案1】:

Secret 类中的 Word 实例不是模拟的实例,您的 Secret 类在每次实例化时都会创建一个新实例。

Secret 类中创建一个新的构造函数:

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

并在您的测试方法中传递您的模拟:

@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"));
}

【讨论】:

  • 我想在不添加新构造函数的情况下这样做,可以吗?
  • 虽然我不推荐它,但是是的,如果你想这样做,你可以像这样使用 PowerMockito:whenNew(Word.class).withNoArguments().thenReturn(myWordInstance); myWordInstance 是您创建的模拟或实例。
【解决方案2】:

您正在 Secret 构造函数中创建一个新的 Word 实例,该构造函数未被模拟。 通过使用@Mock 注释测试类中的Word 成员,Mockito 创建了Word 的模拟实例。

您必须将模拟的Word 实例带入您的Secret instance.e.g。通过构造函数

public class Secret {

    private String secret;
    private Word word;

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

【讨论】:

  • 是的,这对我有用,但我希望能够在不通过构造函数中的参数的情况下做到这一点。 ¿有可能吗?
  • 您可以使用依赖注入来注入 Word 的实例。完成例如春天。你用 Spring 吗?
  • 但是,使用 powermockito.whenNew() 是否可行?
  • 我还没有使用power powermock,它可以工作。
【解决方案3】:

您可以使用Reflection,这通常不太好 - 但对于测试来说并不重要:

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"));

【讨论】:

    猜你喜欢
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 2023-04-05
    • 2022-01-02
    相关资源
    最近更新 更多