- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用 mocha 作为我的 API 应用程序的测试驱动程序。
我有一个包含用户名和歌曲名称的 json,我正在尝试将其提供给 API 端点。
json:
{
"description": "hold the lists that each user heard before",
"userIds":{
"a": ["m2","m6"],
"b": ["m4","m9"],
"c": ["m8","m7"],
"d": ["m2","m6","m7"],
"e": ["m11"]
}
}
假设用户和歌曲架构只是 _id 和名称。我想要做的是解析 json 文件后,通过按名称对“a”进行 Mongoose 查找,将“a”转换为 user_id,假设 id=0。将每个“m2”按名称转换为song_id(假设id=1),然后调用请求,http://localhost:3001/listen/0/1
这是迄今为止我的 Mocha 测试:
测试.js:
it('adds the songs the users listen to', function(done){
var parsedListenJSON = require('../listen.json')["userIds"];
//console.log(parsedListenJSON);
for (var userName in parsedListenJSON) {
if (parsedListenJSON.hasOwnProperty(userName)) {
var songs = parsedListenJSON[userName];
var currentUser;
//console.log(userName + " -> " + songs);
var userQuery = User.findOne({'name': userName})
userQuery.then(function(user){
//console.log("user_id: " + user["_id"]);
currentUser = user;
});
for (var i=0; i<songs.length; i++)
{
//console.log(songs[i]);
var songQuery = Song.findOne({'name': songs[i]})
songQuery.then(function(song){
console.log("user_id: " + currentUser["_id"]);
console.log("song_id: " + song["_id"]);
// need to ensure we have both the user_id and song_id
api_request = "http://localhost:3001/listen/" + currentUser["_id"] + "/" + song["_id"];
console.log(api_request);
// listen/user_id/song_id
//.post('http://localhost:3001/listen/0/1')
request
.post(api_request)
.end(function(err, res){
expect(res.status).to.equal(200);
});
});
}
}
}
done();
})
问题:
1) 在进行 API 校准之前,我需要确保拥有 user_id 和 Song_id。现在,每个 User.findOne 和 Song.findOne 查询都有自己的 then 子句。我通过 currentUser 变量将 user_id 传递到歌曲查询的 then block 中。但由于查询是异步的,我认为这是不正确的。如何构造此代码,以便在执行了 then block 后继续执行 API 调用。
2)当我按原样运行代码时,只有第一个用户被执行,而不是其余的,IE。打印输出是:用户 ID:0歌曲 ID:1 http://localhost:3001/listen/0/1用户 ID:0歌曲 ID:5 http://localhost:3001/listen/0/5
3) API 端点与 postman 一起使用,并在下面的更简单的 Mocha 测试中进行。但它在我原来的代码中似乎不起作用。
var request = require('superagent');
var expect = require('expect.js');
var User = require('../models/user');
var Song = require('../models/song');
var mongoose = require('mongoose');
mongoose.connect('localhost/TestSongRecommender');
...
it('adds the songs', function(){
request
.post('http://localhost:3001/listen/0/2')
.end(function(res){
expect(res.status).to.equal(200);
});
});
更新:
async.forEach 方法有效。这是我的最终片段:
更新了 test.js
var request = require('superagent');
var expect = require('expect.js');
var async = require('async');
var User = require('../models/user');
var Song = require('../models/song');
var mongoose = require('mongoose');
mongoose.connect('localhost/Test');
describe('song recommendations', function(){
it('adds the songs the users listen to', function(done){
var parsedListenJSON = require('../listen.json')["userIds"];
//console.log(parsedListenJSON);
async.forEach(Object.keys(parsedListenJSON), function forAllUsers(userName, callback) {
var songs = parsedListenJSON[userName];
//var currentUser;
//console.log(userName + " -> " + songs);
var userQuery = User.findOne({'name': userName})
userQuery.then(function(user){
//console.log("user_id: " + user["_id"]);
//console.log(songs);
//currentUser = user;
async.forEach(songs, function runSongQuery(songName, smallback) {
//console.log(songName);
var songQuery = Song.findOne({'name': songName})
songQuery.then(function(song){
//console.log("user_id: " + user["_id"]);
//console.log("song_id: " + song["_id"]);
// need to ensure we have both the user_id and song_id
api_request = "http://localhost:3001/listen/" + user["_id"] + "/" + song["_id"];
console.log(api_request);
// listen/user_id/song_id
//.post('http://localhost:3001/listen/0/1')
request
.post(api_request)
.end(function(err, res){
expect(res.status).to.equal(200);
smallback()
});
});
}, function allSongs(err) {
callback();
})
});
}, function allUserNames(err) {
done()
})
})
});
最佳答案
1&2) 您将需要使用 NPM 中的异步包。您可以在主文件夹中使用命令 npm install async --save
并在代码中使用 var async = require('async')
来获取它。
您必须将每个 for 循环替换为 async.forEach。 async.forEach 接受一个数组和两个函数作为参数。它对数组中的每个项目调用第一个函数,并在所有回调返回后调用第二个函数。
你目前使用 for 循环的方式是行不通的。当异步事物返回时,您的循环已迭代它们(记住非阻塞 IO),并且您的变量不再正确设置。
您还需要设置一些内容,以便仅在所有代码运行后调用“done”。
如果编写正确的话,它最终会看起来像这样:
it('adds the songs the users listen to', function(done){
var parsedListenJSON = require('../listen.json')["userIds"];
//console.log(parsedListenJSON);
async.forEach(parsedListenJSON, function forAllUsers(userName, callback) {
var songs = parsedListenJSON[userName];
//console.log(userName + " -> " + songs);
var userQuery = User.findOne({'name': userName})
userQuery.then(function(user){
//console.log("user_id: " + user["_id"]);
var currentUser = user;
async.forEach(songs, function runSongQuery(songName, smallback) {
var songQuery = Song.findOne({'name': songName})
songQuery.then(function(song){
console.log("user_id: " + currentUser["_id"]);
console.log("song_id: " + song["_id"]);
// need to ensure we have both the user_id and song_id
api_request = "http://localhost:3001/listen/" + currentUser["_id"] + "/" + song["_id"];
console.log(api_request);
// listen/user_id/song_id
//.post('http://localhost:3001/listen/0/1')
request
.post(api_request)
.end(function(res){
expect(res.status).to.equal(200);
smallback()
});
});
}, function allRan(err) {
callback();
})
});
}, function allUserNames(err) {
done()
})
})
3) 您将需要使用测试框架来测试您的 API。我推荐supertest 。进行 super 测试后,需要您的应用程序和 super 测试:
var request = require('supertest');
var app = require('./testApp.js');
在以下测试中使用它:
request(app)
.post(api_request)
.end(function(res){
expect(res.status).to.equal(200);
smallback()
});
关于node.js - 在 Mocha 测试中的 for 循环中进行顺序 Mongoose 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38188367/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!