【问题标题】:how to ignore the argument passed to a method being mocked如何忽略传递给被模拟方法的参数
【发布时间】:2019-03-08 22:13:29
【问题描述】:

我正在使用Mockito 测试我的scalaplay 代码。我的代码使用 save 方法,该方法采用 User 参数。我不关心传递给save 的值。我尝试将此行为编码如下

when(mockUserRepository.save(any())).thenReturn(Future(Some(user)))

但我得到错误

Error:(219, 36) not found: value any when(mockUserRepository.save(any())).thenReturn(Future(Some(user)))

mockito中的scala代码指定any的方法是什么?

在我的build.sbt。我只下载了mockito-core。我还需要其他东西吗?

"org.mockito" % "mockito-core" % "2.24.5" % "test"

【问题讨论】:

    标签: scala mockito


    【解决方案1】:

    你可以使用org.mockito.Matchers

    import org.mockito.Mockito._
    import org.mockito.Matchers._
    
    val mockUserRepository = mock[call_your_MockUserRepositiry_service] 
        // something like below 
        // val service = mock[Service[Any, Any]] OR
        // val mockService = mock[MyService]
    
    when(mockUserRepository.save(any)) thenReturn(Future(Some(user)))
    

    请参考https://www.programcreek.com/scala/org.mockito.Matchers

    更新:

    如果MatchersMockito 2.0 中被弃用,那么您可以使用org.mockito.ArgumentMatchers

    In Java Something like below

    class Foo{
        boolean bool(String str, int i, Object obj) {
            return false;
        }
    }
    
    Foo mockFoo = mock(Foo.class);
    when(mockFoo.bool(anyString(), anyInt(), any(Object.class))).thenReturn(true);
    

    In Scala something like below

    def setupService(inputResponse: Future[Unit]): AdminService = {
        val mockConnector = mock[MongoConnector]
    
        when(mockConnector.putEntry(ArgumentMatchers.any(), ArgumentMatchers.any())(ArgumentMatchers.any()))
          .thenReturn(inputResponse)
    
        new AdminService(mockConnector)
      }
    

    希望对你有帮助!

    【讨论】:

    • 谢谢。我已经读过“Mockito 2.0”中不推荐使用“Matchers”。有其他方法吗?
    • 然后您可以使用org.mockito.ArgumentMatcher 模拟给定类型的任何参数的行为。
    【解决方案2】:

    尝试any[User] 而不是any()

    【讨论】:

    • 类似错误Error:(221, 36) not found: value any when(mockUserRepository.save(any[User])).thenReturn(Future(Some(user)))
    • 为了让任何[用户]工作,我必须在buld.sbt中包含"org.mockito" %"mockito-all"%"1.10.19"%"test"而不是"org.mockito" % "mockito-core" % "2.24.5" % "test",并在规范文件中执行import org.mockito.Matchers.any。我不确定这是否是正确的方法
    【解决方案3】:

    我想说,为了避免这个问题以及与 Scala-Java 互操作性相关的许多其他问题,您应该使用 Scala 版本的 Mockito (mockito-scala),在混合特征 org.mockito.ArgumentMatchersSugar 之后,您可以编写

    when(mockUserRepository.save(*)).thenReturn(Future(Some(user)))
    

    或者,如果您喜欢更类似于 scala 的语法

    mockUserRepository.save(*) shouldReturn Future(Some(user))
    

    查看自述文件以查看更多示例和 scala 特定功能

    【讨论】:

    • 感谢布鲁诺。尝试mockito-scala 将在我的脑海中。目前,我对unit-testing 还很陌生,并且已经花了一些时间来了解mockito。在转到mockito-scala 之前,我想进一步了解Mockito
    • 如果我使用mockito-scala,我能模拟objects。我知道这是mockito 的问题,解决方案似乎是powermockito
    • 你不会的,如果你需要模拟objects,这通常暗示你的设计有问题
    • 好的。据我所知,package objects 是在Scala 中创建全局方法的方式。我想知道我怎么能模拟这样的方法。如果你不介意,可以看看这个stackoverflow.com/questions/55089128/…
    • 是的,但是那些全局函数通常是小型实用程序的纯函数,如果您有足够复杂的东西需要为了测试而模拟,您应该将其建模为特征/类,然后注入依赖项(作为构造函数参数或作为使用它的函数的额外参数),然后在测试代码中您可以用模拟替换它
    猜你喜欢
    • 2018-07-30
    • 1970-01-01
    • 2018-07-24
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    相关资源
    最近更新 更多