2013-01-01 56 views
2

这可能与异步代码有关,但我不确定是什么。当我将它们彼此分开运行时,两者都通过:mocha test/models.coffeemocha 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

我发现,由于某些原因,当与npm test一起运行测试时,public.username索引被删除。但在单独运行每个测试时仍保留。

我改变了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内部猫鼬的功能,但对于某些被删除测试生命周期中的原因。

使用猫鼬3.5.4

+1

彼得提到的原因可能是,集合被丢弃而没有管理它的回调。删除一个集合完全删除它,索引,数据,所有它。下一次插入文档时,mongo会再次自动创建一个集合,但索引将不再存在,因为它将是一个全新的集合。行使你的回调,并考虑删除集合中的所有文档,而不是删除。 – aaronheckmann

+0

谢谢,使用User.find({})。remove的好建议 – nak

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语句开头(第1语句)每describe/before/it,并呼吁done(),看他们是否准确显示您所期望的顺序另一个前夕。

+0

仍然有同样的问题,但好建议。我应该学习如何使用异步库来做类似这样的事情? – nak

+0

好吧,我删除了我以前的评论,因为我太过于热心了。我编辑了我的问题,并添加了'models.coffee',这可能是我的问题所在。我有一种感觉,我尝试创建一个可以加载模型的对象并不像预期的那样工作,并且当我的两个测试需要时创建两个单独的模型实例。我可能只是重构模型加载代码,直到它工作...明天! – nak

+0

我发现,由于某种原因,我在使用'npm test'运行时失去了'public.username'的索引...所以我使用适当的值调用了'User.collection.ensureIndex()'在前一步中的任一User.create中,它都可以工作。 – nak

相关问题