这可能与异步代码有关,但我不确定是什么。当我将它们彼此分开时,两者都会通过:mocha test/models.coffee
和mocha test/login.coffee
但是当我与describe 'saving another user with same username', ->
一起运行测试时,npm test
失败了。我想数据库在运行该步骤时会被清除,因此它会保存而不是产生错误,因为它应该是一个唯一值。
另外:我对这个软件测试非常陌生,如果有人有任何提示,或者想批评我的公然错误,请随时给我发电子邮件(查看我的个人资料)
谢谢!
这是我的两个测试文件(coffeescript):
/test/models.coffee
should = require 'should'
{User} = require '../models'
# function to find our test user, John Egbert
findJohn = (cb) ->
User.findOne {'public.username': 'john'}, (err, john) ->
throw err if err
cb(john)
before (done) ->
# Drop all users from database
User.collection.drop()
# Create our test user, his username is John Egbert
User.create
password: 'test123'
public: {username: 'john'}, done
describe 'create user', ->
it 'should create a document that can be found', (done) ->
findJohn (user) ->
should.exist user
done()
describe 'user password', ->
it 'should NOT be stored in plaintext', (done) ->
findJohn (user) ->
user.password.should.not.eql 'test123'
done()
it 'should return true for matching password', (done) ->
findJohn (user) ->
user.comparePassword 'test123', (err, isMatch) ->
isMatch.should.eql true
done()
it 'should return false for non-matching password', (done) ->
findJohn (user) ->
user.comparePassword 'wrong_password', (err, isMatch) ->
isMatch.should.not.eql true
done()
describe 'saving another user with same username', ->
it 'should produce an error', (done) ->
User.create public: {username: 'john'}, (err) ->
should.exist err
done()
/test/login.coffee
:
should = require 'should'
{User} = require '../models'
login = require '../services/login'
before (done) ->
# Drop all users from database
User.collection.drop()
# Create our test user, his username is John Egbert
User.create
password: 'test123'
public: {username: 'john'}, done
describe 'login', ->
it 'should return true for an existing username/password combo', (done) ->
login username: 'john', password: 'test123', (err, loggedIn) ->
should.not.exist(err)
loggedIn.should.be.true
done()
it 'should return false for a bad username/password combo', (done) ->
login username: 'john', password: 'wrong_pass', (err, loggedIn) ->
should.not.exist(err)
loggedIn.should.be.false
done()
/models.coffee
fs = require 'fs'
path = require 'path'
mongoose = require 'mongoose'
#Connect to mongodb
#TODO: env variable to choose production/development/testing databases
mongoose.connect 'localhost', 'siglr'
models = {}
for file in fs.readdirSync './schemas'
if path.extname(file) is '.coffee'
modelName = path.basename file, '.coffee'
schema = require "./schemas/#{modelName}"
models[modelName] = mongoose.model modelName, schema
# key is model name, value is actual mongoose model
module.exports = models
答案 0 :(得分:2)
这有一件事可能会造成让你疯狂的竞争条件。删除用户集合时,您没有传递回调。我不能确定这是否会导致问题,例如在集合被删除之前插入测试用户,但是这种无法正确使用回调以等待异步操作完成的模式是您的程序的一个方法以难以调试的方式行为不端。试试这个:
before (done) ->
# Drop all users from database
User.collection.drop (err) ->
# Create our test user, his username is John Egbert
User.create
password: 'test123'
public: {username: 'john'}, done
第二个建议:在console.log
之前将describe/before/it
个语句放在第一个语句的开头(第一个语句),然后在调用done()
之前放置另一个语句,看看它们是否按照您期望的顺序出现
答案 1 :(得分:0)
我发现由于某种原因,在与public.username
一起运行测试时会删除npm test
索引。但是在单独运行每个测试时都得到了维护。
我在test/models.coffee
:
# Create our test user, his username is John Egbert
User.create
password: 'test123'
public: {username: 'john'}, done
以下内容:
# Create our test user, his username is John Egbert
User.create
password: 'test123'
public: {username: 'john'}, ->
User.collection.ensureIndex { 'public.username': 1 }, { unique: true }, (err) ->
throw err if err
done()
...调用ensureIndex一个名为when the model is compiled initially的内部mongoose函数,但在测试的生命周期中由于某种原因被删除。
使用Mongoose 3.5.4