如何在 Spock 中使用 jmockit 来测试 return 多个不同值的静态方法?

How to use jmockit in Spock to test static methods to return multiple different values?

我想用jmockit来测试Spock中的静态方法,结合where标签实现每个mock的不同值来测试不同的业务逻辑。我尝试了很多写作方法,但都失败了。我希望我能在这里得到帮助或建议。非常感谢

这是我的业务代码示例:

public class MyUtils {
    public static int staticMethod(int origin) {
        return 0;
    }
}
public class MyClass {    
    public void verify(int origin) {
        if (MyUtils.staticMethod(origin) == 1) {
            System.out.println("1");
        }
        if (MyUtils.staticMethod(origin) == 2) {
            System.out.println("2");
        }
        ...
    }
}

这是我的Spock测试代码:

def "verify"() {
    when:
    myClass.verify(0)

    then:
    true

    where:
    mock | _
    mockStatic(1) | _
    mockStatic(2) | _
}

def mockStatic(val){
    new MockUp<MyUtils>() {
        @Mock
        public int staticMethod(int origin) {
            return val
        }
    }
}

我知道power可以实现这样的功能,但是因为我们团队一直在使用jmockit,所以想知道jmockit是否可以在Spock中实现mock这样的多个不同值?

将您的方法调用放入闭包中,并在每次迭代期间评估闭包:

package de.scrum_master.Whosebug.q67882559

import mockit.Mock
import mockit.MockUp
import mockit.internal.state.SavePoint
import spock.lang.Requires
import spock.lang.Specification
import spock.lang.Unroll

class StaticMethodJMockitTest extends Specification {
  def jMockitSavePoint = new SavePoint()

  def cleanup() {
    jMockitSavePoint.rollback()
  }

  @Unroll
  def "verify"() {
    given:
    mockClosure()
    MyClass myClass = new MyClass()

    when:
    myClass.verify(0)

    then:
    true

    where:
    mockClosure << [
      { /* no mock */ },
      { mockStatic(1) },
      { mockStatic(2) }
    ]
  }

  def mockStatic(val) {
    new MockUp<MyUtils>() {
      @Mock
      int staticMethod(int origin) {
        return val
      }
    }
  }

  public static class MyUtils {
    public static int staticMethod(int origin) {
      return 0;
    }
  }

  public static class MyClass {
    public void verify(int origin) {
      if (MyUtils.staticMethod(origin) == 1) {
        System.out.println("1");
      }
      if (MyUtils.staticMethod(origin) == 2) {
        System.out.println("2");
      }
    }
  }
}

如果您希望使用数据 tables,您需要通过在闭包中显式添加 it -> 来帮助解析器,如果闭包位于数据的第一列中table。您还可以为展开的迭代使用一些漂亮的命名:

  @Unroll
  def "verify #description"() {
    given:
    mockClosure()
    MyClass myClass = new MyClass()

    when:
    myClass.verify(0)

    then:
    true

    where:
    description     | mockClosure
    "no mock"       | { /* no mock */ }
    "mock result 1" | { mockStatic(1) }
    "mock result 2" | { mockStatic(2) }
  }

创建和回滚保存点的原因是 JMockit 在模拟生命周期方面与 Spock 的配合不佳,维护者甚至无意提供帮助。有关详细信息,请参阅 JMockit issue #668