【问题标题】:Override Spock mock with method instead of value用方法而不是值覆盖 Spock 模拟
【发布时间】:2020-11-23 02:22:21
【问题描述】:

我知道使用 Spock 我可以创建一个 Mock 并在方法上设置返回值,例如

    idpClient.adminCreateUser(_) >> [
            user: new UserType()
    ]

如何在 Mock 上设置方法,以便自定义返回的值?我想做类似的事情:

    idpClient.metaClass.adminCreateUser = { AdminCreateUserRequest adminCreateUserRequest ->
        UserType user = new UserType()
        user.setUsername(adminCreateUserRequest.getUsername())
        AdminCreateUserResult result = new AdminCreateUserResult()
        result.setUser(user)
        return result
    }

虽然显然上述方法不起作用(它返回 null)。我查看了文档,但我发现的只是如何返回一个固定值(见上文)。

【问题讨论】:

    标签: groovy spock


    【解决方案1】:

    也许您应该阅读 Spock 手册。在computing return values 上有一个部分。无需使用元类,Spock DSL 为存根提供了句法手段。

    我为你编了这个小例子作为MCVE

    package de.scrum_master.stackoverflow.q64961803;
    
    class UserType {
      private String userName;
      public void setUserName(String userName) { this.userName = userName; }
      public String getUserName() { return userName; }
    }
    
    package de.scrum_master.stackoverflow.q64961803;
    
    public class AdminCreateUserResult {
      private UserType user;
      public void setUser(UserType user) { this.user = user; }
      public UserType getUser() { return user; }
    }
    
    package de.scrum_master.stackoverflow.q64961803;
    
    public class AdminCreateUserRequest {
      private String userName;
      public AdminCreateUserRequest(String userName) { this.userName = userName; }
      public String getUserName() { return userName; }
    }
    
    package de.scrum_master.stackoverflow.q64961803;
    
    public class IDPClient {
      public AdminCreateUserResult adminCreateUser(AdminCreateUserRequest adminCreateUserRequest) {
        AdminCreateUserResult userResult = new AdminCreateUserResult();
        UserType userType = new UserType();
        userType.setUserName("real user");
        userResult.setUser(userType);
        return userResult;
      }
    }
    

    相应的 Spock 规范如下所示:

    package de.scrum_master.stackoverflow.q64961803
    
    import spock.lang.Specification
    
    class IDPClientTest extends Specification {
      def test() {
        given: "mock IDPClient with stubbed method"
        IDPClient idpClient = Mock() {
          adminCreateUser(_) >> { AdminCreateUserRequest adminCreateUserRequest ->
            UserType user = new UserType()
            user.setUserName(adminCreateUserRequest.getUserName())
            AdminCreateUserResult result = new AdminCreateUserResult()
            result.setUser(user)
            result
          }
        }
        def request = new AdminCreateUserRequest("test user")
    
        expect: "real IDPClient behaves normally"
        new IDPClient().adminCreateUser(request).user.userName == "real user"
    
        and: "mock IDPClient displays stub behaviour"
        idpClient.adminCreateUser(request).user.userName == "test user"
      }
    }
    

    【讨论】:

    • 我确实阅读了手册并尝试过 - 仍然返回 null。
    • 你真的试过我的例子吗?也许你的不一样,否则它会起作用。我需要查看MCVE,但至少需要查看正在测试的课程。我无法调试无法重现的内容。只是贴一个小测试sn-p,说它不起作用,这不是问问题的好方法。让我的努力值得,请做好你的功课。 MCVE 本来是你的工作,而不是我的工作。我没有冒犯的意思,只是想非常清楚我需要什么来帮助你。
    • 您没有展示如何实例化模拟,我无法验证存根方法是否可能是最终的(这意味着存根将无效)以及我想要检查的其他内容。
    • 请反馈。谢谢。
    • 嗯,嗯,这样回答你的问题并不是特别值得。我投入了时间、精力,甚至制作了一个完整的 MCVE,它可以证明是有效的。如果您太忙而无法在这里回答您自己的问题,最好不要一开始就问。请您至少支持并接受我的正确答案,而不是直言不讳地说您不记得并继续前进吗?老实说,我觉得这不太好。随后,我们都可以删除有关此问题的最新 cmets。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 2012-10-26
    • 2020-06-11
    相关资源
    最近更新 更多