【发布时间】:2013-10-13 08:56:25
【问题描述】:
我在服务类中有一个静态地图。我正在对填充地图的方法进行单元测试。我想知道如何模拟服务类中使用的地图。
SomeService
--------------
class SomeService {
static Map<Integer,String> tempMap = new HashMap<Integer,String>()
//This map is used in some other service api
}
OtherService
------------
class OtherService {
void method1(Integer i, String str) {
// here it populates the map
def test = SomeService.tempMap.put(i,str)
println "After putting : "+test
}
}
单元测试用例
OtherServiceTests
------------------
class OtherServiceTests {
void testMethod1() {
def mockedMap = mockFor(Map)
SomeService.metaClass.static.tempMap = mockedMap.createMock()
SomeService.metaClass.static.tempMap.put = {Integer i, String str -> "Testing"} // how to mock??
}
}
当我运行测试用例时,它调用的是真实地图,而不是使用模拟的 "put" api,它返回 null 而不是“测试”
我尝试了几种方法来模拟它,但仍然没有运气。如何模拟 Map api 这是服务类的 static 属性?
【问题讨论】:
-
Grails 服务是单例的,因此您不应在其中存储状态(仅声明方法)。
-
@SérgioMichels Michels 我希望这张地图可以从不同的地方访问。涉及多个 put 和 get 操作。如果以这种方式访问地图会产生问题吗? Service1 将填充地图。 Service2 将从地图中获取信息。请告知。
-
100% 会产生问题。正如他所说,服务是单例的,因此它们保持状态。服务中存在的任何全局范围的字段都将在无状态请求中可用,这将导致错误的结果。强烈建议不要在服务中添加作用域变量。您可以尝试使用其他符合您要求的服务范围,或者完全放弃在服务类中使用静态全局地图的想法。
-
@dmahapatro 我的方法是创建一个静态地图,所有无状态请求都应该访问该地图。如果请求包含正确的密钥,则允许修改映射,并且如果它使用相同的密钥访问,则所有其他请求都应该可以看到它。那么在这种情况下会出现什么问题?对不起,如果我错过了什么......我我只是困惑..:(
-
但是如果您将应用程序作为两个单独的实例运行并尝试对它们进行负载平衡,那么虽然这将是一个静态字段,但它仍然是内存中的不同对象 - 每个 tomcat 实例一个映射,并且它不会包含相同的数据
标签: unit-testing grails map