我对这个问题的处理方法可能完全错误,所以请不要犹豫,纠正它。我还在问题标题中添加了 ATDD,因为我正在尝试测试我的 web api 的输出,这不仅仅是一个单元测试。
我在用:
- 谷歌应用引擎 1.7.1
- GAE 高复制数据存储
- Python 2.7.3
我使用样板代码设置我的测试:
self.testbed = testbed.Testbed()
self.testbed.activate()
self.policy = datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=0)
self.testbed.init_datastore_v3_stub()
然后我调用一个模拟对象设置来设置我的实体并将它们保存到测试平台数据存储区。我使用计数器添加 5 位艺术家 ID 为 1 - 5 的艺术家:
def add_mock_artist_with(self, artist_id, link_id, name):
new_artist = dto.Artist(key_name=str(artist_id),
name=name,
link_id= str(link_id))
new_artist.put()
我的测试是我的 web api 返回:
{
"artists": [
{
"artist": {
"name": "Artist 1",
"links": {
"self": {
"href": "https://my_server.com/artist/1/"
}
}
}
},
.
.
.
{
"artist": {
"name": "Artist 5",
"links": {
"self": {
"href": "https://my_server.com/artist/5/"
}
}
}
}
],
"links": {
"self": {
"href": "https://my_server.com/artists/"
}
}
}
最初我想如果我每次运行测试时都启动一个新的测试平台,我可以指望我的艺术家按顺序输入到数据存储中,因此会得到 ids 1 - 5。我的测试最初通过了,但随着时间的推移由于 id 不匹配而开始失败(我会得到一个链接,如:“href”:“https://my_server.com/artist/78/”)。依赖顺序生成的 id 让我感到有点内疚,所以我决定修复它。我偶然发现了键是名称或生成的 id 的概念。我更新了返回 JSON 的模板以供使用:
artist.key().id_or_name()
在模拟对象的情况下,我在构造时提供了键名:
key_name=str(artist_id)
对于非模拟构造,我没有包含那行代码并让 GAE 分配 id。
由于我的模板使用 key().id_or_name() 来输出属性,所以一切顺利并且测试通过了。
但是,现在当我测试可以通过以下http://my_server.com/artist/5/访问的单个艺术家的返回时,我的测试失败了。要将艺术家从数据存储中取出,我使用以下代码:
def retrieve_artist_by(id):
artist = dto.Artist.get_by_id()
在生产中,这会很好,因为它都是基于 id 的。但是,在我的测试中,它没有找到任何东西,因为我在模拟构造中使用了 key_name=str(artist_id) ,并且名称与 id 不同。
我希望有类似的东西:
artist = dto.Artist.get_by_id_or_name()
有任何想法吗?