【问题标题】:Spock Power Mock does not return value specified in .thenAnswer { } methodSpock Power Mock 不返回 .thenAnswer { } 方法中指定的值
【发布时间】:2020-01-30 20:20:51
【问题描述】:

我有一个具有public static void 方法的类。此方法使用不同类中的方法,此方法接受两个参数并返回一个List 值。

public class FirstClass {
    public static void doSomething() {
        List<String> values = SecondClass.getOrderedValuesBy(anotherMethod());
        // action 
    }

    private static String anotherMethod() {
        // some action
        return ""; // something that depends on action above.
    }
}

public class SecondClass {
    public static List<String> getOrderedValuesBy(String by) {
        List<String> values = new ArrayList<>();
        values.addAll(getOrderedValuesBy(by, true));
        return values;
    }

    private static List<String> getOrderedValuesBy(String by, boolean ordered) {
       // some action
    }
}

然后在为此编写一些测试时,我在SecondClass 上使用mockStatic 方法并将FirstClass 初始化为一个新对象,如下所示。

def "someTest"() {
    given:
    mockStatic(SecondClass)
    FirstClass firstClass = new FirstClass()
    when(SecondClass.getOrderedValuesBy(anyString()).thenAnswer {['some values'])}
}

它不会返回我想要的这些值,因为我需要在doSomething() void 方法中调用的一些私有方法中使用它们,并且作为参数,这些方法采用values 列表。有人知道我做错了什么,以及我如何操作在FirstClass中的void方法中调用的这个方法返回的值@

【问题讨论】:

  • 您需要使用.thenReturn 而不是.thenAnswer,因为您要返回一个值。 .thenAnswer 用于在提供返回值之前运行附加代码。
  • @Jordan 它似乎工作正常,谢谢!
  • @Jordan,请将您的评论变成 OP 可以接受的答案,以结束问题。还请解释为什么thenAnswer 如果使用正确将无法工作。它也可以返回一个值,即使在这里使用它可能有点过度设计。
  • 我现在自己也试过了,thenAnswer 效果很好。问题一定出在其他地方。
  • @Gstark,你问了一个问题,我回答了。我会很感激一些反馈。这是有礼貌的人通常在 SO 上做的事情。所以请检查我的回答,如果你认为它是正确的,请接受+upvote(我当然这样做)。

标签: java groovy spock powermock


【解决方案1】:

您可以同时使用thenReturnthenAnswer,这取决于您在返回值之前要做什么,正如@Jordan 所说。这是MCVE

应用程序类:

package de.scrum_master.stackoverflow.q59993907;

import java.util.ArrayList;
import java.util.List;

public class SecondClass {
  public static List<String> getOrderedValuesBy(String by) {
    List<String> values = new ArrayList<>();
    values.addAll(getOrderedValuesBy(by, true));
    return values;
  }

  private static List<String> getOrderedValuesBy(String by, boolean ordered) {
    // some action
    List<String> result = new ArrayList<>();
    result.add("one");
    result.add("two");
    result.add("three");
    return result;
  }
}
package de.scrum_master.stackoverflow.q59993907;

import java.util.List;

public class FirstClass {
  public static void doSomething() {
    List<String> values = SecondClass.getOrderedValuesBy(anotherMethod());
    // action
    System.out.println(values);
  }

  private static String anotherMethod() {
    // some action
    return ""; // something that depends on action above.
  }
}

使用 PowerMockito 的 Spock 规范:

package de.scrum_master.stackoverflow.q59993907

import org.junit.runner.RunWith
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner
import org.powermock.modules.junit4.PowerMockRunnerDelegate
import org.spockframework.runtime.Sputnik
import spock.lang.Specification

import static de.scrum_master.stackoverflow.q59993907.SecondClass.getOrderedValuesBy
import static org.mockito.ArgumentMatchers.anyString
import static org.powermock.api.mockito.PowerMockito.mockStatic
import static org.powermock.api.mockito.PowerMockito.when

@RunWith(PowerMockRunner)
@PowerMockRunnerDelegate(Sputnik)
@PrepareForTest(SecondClass)
class PowerMockStaticTest extends Specification {
  static final PrintStream originalSysOut = System.out
  PrintStream mockSysOut = Mock()

  def setup() {
    System.out = mockSysOut
  }

  def cleanup() {
    System.out = originalSysOut
  }

  def "no mock"() {
    when:
    FirstClass.doSomething()

    then:
    1 * mockSysOut.println(['one', 'two', 'three'])
  }

  def "when-thenAnswer"() {
    given:
    mockStatic(SecondClass)
    when(getOrderedValuesBy(anyString())).thenAnswer { ['thenAnswer'] }

    when:
    FirstClass.doSomething()

    then:
    1 * mockSysOut.println(['thenAnswer'])
  }

  def "when-thenReturn"() {
    given:
    mockStatic(SecondClass)
    when(getOrderedValuesBy(anyString())).thenReturn(['thenReturn'])

    when:
    FirstClass.doSomething()

    then:
    1 * mockSysOut.println(['thenReturn'])
  }
}

【讨论】:

  • 更新:我在测试中添加了带有实际条件检查的 when-then 块,而不是手动检查控制台输出。
猜你喜欢
  • 2018-08-06
  • 1970-01-01
  • 2011-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
相关资源
最近更新 更多