scala - 在 Scala 中模拟新对象的创建
问题描述
我想为下面的 scala 类编写单元测试。在下面的实现中,QueryConfig 是最终案例类。
class RampGenerator {
def createProfile(queryConfig: QueryConfig): String = {
new BaseQuery(queryConfig).pushToService().getId
}
}
我写的单元测试是这样的
@RunWith(classOf[JUnitRunner])
class RampGeneratorTest extends FlatSpec with Matchers {
"createProfile" must "succeed" in {
val rampGenerator = new RampGenerator()
val queryConfig = QueryConfig("name", "account", “role")
val baseQuery = mock(classOf[BaseQuery])
val profile = mock(classOf[Profile])
when(new BaseQuery(queryConfig)).thenReturn(baseQuery)
when(baseQuery.pushToService()).thenReturn(profile)
when(profile.getId).thenReturn("1234")
val id = rampGenerator.createProfile(queryConfig)
assert(id.equals("1234"))
}
}
目前它给出了以下异常,这是预期的,因为我没有在什么时候使用过模拟类。如何模拟新实例的创建?
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
解决方案
有两种选择:
- 使用 powermockito 模拟构造函数(有关详细信息,请参阅此问题)
- 外部化对象创建
关于第二个选项的更多信息 - 这实际上是一种在各种情况下都有帮助的测试技术(几个例子:你的,创建 akka 演员并在层次结构上断言) - 所以将它放在“工具箱”。
在你的情况下,它看起来像这样:
class RampGenerator(queryFactory: QueryFactory) {
def createProfile(queryConfig: QueryConfig) = queryFactory.buildQuery(queryConfig).pushToService().getId()
}
class QueryFactory() {
def buildQuery(queryConfig: QueryConfig): BaseQuery = ...
}
@RunWith(classOf[JUnitRunner])
class RampGeneratorTest extends FlatSpec with Matchers {
"createProfile" must "succeed" in {
val rampGenerator = new RampGenerator()
val queryConfig = QueryConfig("name", "account", “role")
val queryFactory = mock(classOf[QueryFactory])
val profile = mock(classOf[Profile])
val baseQuery = mock(classOf[BaseQuery])
when(queryFactory.buildQuery(queryConfig)).thenReturn(baseQuery)
when(baseQuery.pushToService()).thenReturn(profile)
when(profile.getId).thenReturn("1234")
val id = rampGenerator.createProfile(queryConfig)
assert(id.equals("1234"))
}
}
请注意,查询工厂不必是一个单独的工厂类/类的层次结构(当然也不需要像抽象工厂模式那样重量级的东西——尽管你可以使用它)。特别是,我的初始版本只是使用queryFactory: QueryConfig => BaseQuery
函数,但 mockito 不能模拟函数......
如果您更喜欢直接(通过函数)注入工厂方法,Scalamock支持模拟函数
推荐阅读
- javascript - 如何组合线性数组的元素?
- angular - 无法迭代 Angular 6 中的本地对象数组?
- python - 为什么 \x00 没有被 repr 转换为 \0
- jquery - 使用 jQuery ajax 从客户端调用时服务器代码未触发
- android - 为什么在为 Android 编译 FFmpeg 时会出现“错误:无效指令助记符”?
- linux - sed 用多行文件或变量替换行
- sql - Oracle SQL 从数字字段中找出序号
- ios - 如何让 UIView 检测父级比例的变化?
- python - AttributeError:“SelectorList”对象没有“替换”属性
- c# - .NET 4.x 与 .NET 3.5 相比更改了小数点 - 如何解决?(统一)