2016-10-28 31 views
2

我最近跳進和的NodeJS開始建設一箇中間件應用程序了使用快速& Wagnor下面異常行爲:node.js的/摩卡

是我的package.json

{ 
"devDependencies": { 
    "gulp": "3.8.11", 
    "gulp-mocha": "2.0.1", 
    "mocha": "2.2.4", 
    "superagent": "1.2.0", 
    "wagner-core": "0.1.0" 
}, 
    "dependencies": { 
    "underscore": "1.5.2", 
    "mongodb": "2.2.10", 
    "express": "", 
    "http-status": "0.1.8", 
    "mongoose":"" 
}, 
"scripts": { 
"test": "mocha test.js" 
} 
} 

我被困在一個非常奇怪的情況,並尋找類似的事件報告,但沒有任何相關的。我確信我犯了一個愚蠢的錯誤,需要幫助來識別它。

這裏是場景,我有一個基本的中間件設置與6個端點,我正在測試使用摩卡。

我有一個包含6個測試的test.js文件,問題是當我運行它時,它會傳遞一次,並失敗另一個時間,然後再次傳遞,沒有任何干預env或代碼或測試。這使我非常擔心我的應用程序在生產中的行爲會類似,或者它是與測試相關的問題或已知的摩卡問題(找不到任何)。

下面是我的測試文件

var URL_ROOT = 'http://localhost:3131'; 
var express = require('express'); 
var wagner = require('wagner-core'); 
var assert = require('assert'); 
var superagent = require('superagent'); 
var mongoose = require('mongoose'); 
//mongoose.set('debug', true); 

var PRODUCT_ID = '0000000000000000000001'; 

describe('Store API', function(){ 
    var server; 
    var Product; 
    var Catagory; 
    var User; 


    before(function() { 
     var app = express(); 

     // Bootstrap sertver 
     models = require('./models')(wagner); 
     require('./dependencies')(wagner); 
     app.use(require('./api')(wagner)); 
     wagner.invoke(require('./auth'), {app: app}); 
     server = app.listen(3131); 

     //Make Catagory and Product model available in test 
     Catagory = models.Catagory; 
     Product = models.Product; 
     User = models.User; 


     app.use(function(req, res, next) { 
      User.findOne({}, function(error, user) { 
       console.log('Time:', Date.now()); 
       assert.ifError(error); 
       req.user = user; 
       next(); 
      }); //user.findone 
     }); //app.use 
    }); //before 

    after(function(){ 
     //Shut the server 
     server.close(); 
    }); //after 

    beforeEach(function(done) { 
     //Make sure Catagories are empty before each test 
     Catagory.remove({}, function(error) { 
      assert.ifError(error); 
      Product.remove({}, function(error) { 
       assert.ifError(error); 
       User.remove({}, function(error) { 
        assert.ifError(error); 
        //Create Products, Catagories and Users 
        var catagories = [ 
         { _id: 'Electronics'}, 
         { _id: 'Phones', parent: 'Electronics'}, 
         { _id: 'Laptop', parent: 'Electronics'}, 
         { _id: 'Meat'} 
        ]; 

        // create product data 
        var products = [ 
         { 
          _id: '00000000000001', 
          name: 'LG G4', 
          catagory: { _id: 'Phones', ancestors: ['Electronics', 'Phones']}, 
          price: { 
           amount: 300, 
           currency: 'USD' 
          } 
         }, 
         { 
          _id: '00000000000002', 
          name: 'Asus Zenbook Prime', 
          catagory: { _id: 'Laptop', ancestors: ['Electronics', 'Laptop']}, 
          price: { 
           amount: 2000, 
           currency: 'USD' 
          } 
         }, 
         { 
          _id: '00000000000003', 
          name: 'MeatOne Goasht Wala', 
          catagory: {_id: 'Meat', ancestors: ['Meat']}, 
          price: { 
           amount: 20, 
           currency: 'USD' 
          } 
         } 
        ]; 

        var users = [{ 
         profile: { 
          username: 'shoaibhb', 
          picture: 'http://pbs.twimg.com/profile_images/364903575/ShoaibHayat_Butt.jpg' 
         }, 
         data: { 
          oauth: 'invalid', 
          cart: [] 
         } 
        }]; 

        Catagory.create(catagories, function(error) { 
         assert.ifError(error) 
         Product.create(products, function(error) { 
          assert.ifError(error) 
           User.create(users, function(error) { 
            assert.ifError(error); 
            User.findOne({}, function(err, user) { 

            }); 
          }); 
         }); 
        }); 
       }); 
       done(); 
      }); 
     }); 
    }); 

    it('can load a Catagory by id', function(done) { 
     // Create a single Catagory 
     // Catagory.create({ _id: 'Electronics' }, function(error, doc) { 
     //  assert.ifError(error); 
      var url = URL_ROOT + '/catagory/id/Electronics'; 
      //Make and HTTP request to localhost:3131/catagory/id/Electronics 
      superagent.get(url, function(error, res) { 
       assert.ifError(error); 
       var result; 
       // and make sure we got { _id: 'Electronics'} back 
       assert.doesNotThrow(function() { 
        result = JSON.parse(res.text); 
       }); 
       assert.ok(result.catagory); 
       assert.equal(result.catagory._id, 'Electronics'); 
       done(); 
      }); 
     //});// ends here 
    }); 

    it('can load all Catagories that have a certain parent', function(done) { 

     // Create 4 catagories was here earlier, moved to beforeEach() 

     //Catagory.create(catagories, function(error, catagories) { 
      var url = URL_ROOT + '/catagory/parent/Electronics'; 
      //make HTTP request to /catagory/parent/Electronics 
      superagent.get(url, function(error, res) { 
       assert.ifError(error); 
       var result; 
       assert.doesNotThrow(function() { 
        result = JSON.parse(res.text); 
       }); 
       assert.equal(result.catagories.length, 2); 
       // should be in assending order by _id 
       assert.equal(result.catagories[0]._id, 'Laptop'); 
       assert.equal(result.catagories[1]._id, 'Phones'); 
       done(); 
      }); 
     //});// create cat ends here 
    }); 

    it('can load a product by id', function(done) { 
     //Create a single product 


     var oneProduct = { 
       name: 'LG G4', 
       _id: PRODUCT_ID, 
       catagory: { _id: 'Phones', ancestors: ['Electronics', 'Phones']}, 
       price: { 
        amount: 300, 
        currency: 'USD' 
       } 
      }; 

     Product.create(oneProduct, function(error, doc) { 
      assert.ifError(error); 
      var url = URL_ROOT + '/product/id/' + PRODUCT_ID; 
      // Make HTTP request to 
      // localhost:3131/product/id/0000000000000000000001 
      superagent.get(url, function(error, res) { 
       assert.ifError(error); 
       var result = {}; 
       //And make sure we got LG G4 back 

       assert.doesNotThrow(function() { 
        result = JSON.parse(res.text); 
       }); 

       assert.ok(result.product); 
       assert.equal(result.product._id, PRODUCT_ID); 
       assert.equal(result.product.name, 'LG G4'); 
       done(); 
      });  
     }); 
    }); 

    it('can load all products in a Catagory with sub-catagories', function(done) { 

     // moved to beforeEach function 

       var url = URL_ROOT + '/product/catagory/Electronics'; 
       //Make HTTP Request to loca:3131 
       superagent.get(url, function(error, res) { 
        assert.ifError(error); 
        var result; 
        assert.doesNotThrow(function() { 
         result = JSON.parse(res.text);     
        }); 
        assert.equal(result.product.length, 2); 
        // should be assending order by name 
        assert.equal(result.product[0].name, 'Asus Zenbook Prime'); 
        assert.equal(result.product[1].name, 'LG G4'); 

        //Sort by price , assending 
        var url = URL_ROOT + '/product/catagory/Electronics?price=1'; 
        superagent.get(url, function(error, res) { 
         assert.ifError(error); 
         var result; 
         assert.doesNotThrow(function() { 
          result = JSON.parse(res.text); 
         }); 
         assert.equal(result.product[0].name, 'LG G4'); 
         assert.equal(result.product[1].name, 'Asus Zenbook Prime'); 
        }); 
        //console.log(error); 
        assert.ifError(error); 
        done(); 
      }); 
    }); 


    it('can load user cart', function(done) { 
     var url = URL_ROOT + '/me/'; 
     User.findOne({}, function(error, user) { 
      console.log("error %j",error); 
      //assert.ifError(error); 
      user.data.cart = [{ product: PRODUCT_ID, quantity: 1}]; 
      console.log(user.data.cart); 
      user.save(function(error) { 
       assert.ifError(error); 
       superagent.get(url, function(error, res) { 
        assert.ifError(error); 
        assert.equal(res.status, 200); 
        var result; 
        assert.doesNotThrow(function() { 
         result = JSON.parse(res.text).user; 
        }); 
        assert.equal(result.data.cart.length,1); 
        assert.equal(result.data.cart[0].product.name, 'Asus Zenbook Prime'); 
        assert.equal(result.data.cart[0].quantity, 1); 

       }); 
      }); 
     }); 
     done(); 
    }); 



    it('can save user cart', function(done) { 
     var url = URL_ROOT + '/me/cart/'; 

     superagent.put(url).send({ 
      data: { 
       cart: [{ product: PRODUCT_ID, quantity: 1}] 
      } 
     }).end(function(error, res) { 
      assert.ifError(error); 
      assert.equal(res.status, status.OK); 
      User.findOne({}, function(error, user) { 
       assert.ifError(error); 
       assert.equal(user.data.cart.length, 1); 
       assert.equal(user.data.cart[0].product, PRODUCT_ID); 
       assert.equal(user.data.cart[0], quantity, 1); 
      }); 
     }); 
     done(); 
    }); 
    enter code here 

}); 

當我運行這些測試,會出現以下情況: 一)6個測試通過 二)一些測試失敗 C)有一個空白的響應

D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore>mocha test-6passing.js 

D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore>mocha test-6passing.js 


    Store API 
express-session deprecated undefined resave option; provide resave option auth.j 
s:57:39 
express-session deprecated undefined saveUninitialized option; provide saveUnini 
tialized option auth.js:57:39 
    √ can load a Catagory by id (81ms) 
    √ can load all Catagories that have a certain parent 
    √ can load a product by id 
    √ can load all products in a Catagory with sub-catagories 
    √ can load user cart 
error null 
    1) "before each" hook 


    5 passing (752ms) 
    1 failing 

    1) Store API "before each" hook: 
    Uncaught TypeError: Cannot read property 'data' of null 
     at test-6passing.js:243:17 
     at node_modules\mongoose\lib\query.js:1173:16 
     at node_modules\mongoose\node_modules\kareem\index.js:109:16 




D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore>mocha test-6passing.js 


    Store API 
express-session deprecated undefined resave option; provide resave option auth.j 
s:57:39 
express-session deprecated undefined saveUninitialized option; provide saveUnini 
tialized option auth.js:57:39 
    √ can load a Catagory by id (89ms) 
    √ can load all Catagories that have a certain parent (38ms) 
    √ can load a product by id 
    √ can load all products in a Catagory with sub-catagories 
    √ can load user cart 
error null 
    1) "before each" hook 


    5 passing (922ms) 
    1 failing 

    1) Store API "before each" hook: 
    Uncaught TypeError: Cannot read property 'data' of null 
     at test-6passing.js:243:17 
     at node_modules\mongoose\lib\query.js:1173:16 
     at node_modules\mongoose\node_modules\kareem\index.js:109:16 




D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore>mocha test-6passing.js 


    Store API 
express-session deprecated undefined resave option; provide resave option auth.j 
s:57:39 
express-session deprecated undefined saveUninitialized option; provide saveUnini 
tialized option auth.js:57:39 
    √ can load a Catagory by id (96ms) 
    √ can load all Catagories that have a certain parent 
    √ can load a product by id 
    √ can load all products in a Catagory with sub-catagories 
    √ can load user cart 
error null 
    √ can save user cart 


    6 passing (852ms) 


D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore>mocha test-6passing.js 

D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore>mocha test-6passing.js 


    Store API 
express-session deprecated undefined resave option; provide resave option auth.j 
s:57:39 
express-session deprecated undefined saveUninitialized option; provide saveUnini 
tialized option auth.js:57:39 
    √ can load a Catagory by id (80ms) 
    √ can load all Catagories that have a certain parent 
    √ can load a product by id 
    1) can load all products in a Catagory with sub-catagories 
    √ can load user cart 
error null 
    2) "before each" hook 


    4 passing (862ms) 
    2 failing 

    1) Store API can load all products in a Catagory with sub-catagories: 

     Uncaught AssertionError: 0 == 2 
     + expected - actual 

     -0 
     +2 

     at test-6passing.js:215:28 
     at Request.callback (node_modules\superagent\lib\node\index.js:785:12) 
     at IncomingMessage.<anonymous> (node_modules\superagent\lib\node\index.js: 
990:12) 
     at endReadableNT (_stream_readable.js:913:12) 

    2) Store API "before each" hook: 
    Uncaught TypeError: Cannot read property 'data' of null 
     at test-6passing.js:243:17 
     at node_modules\mongoose\lib\query.js:1173:16 
     at node_modules\mongoose\node_modules\kareem\index.js:109:16 




D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore>mocha test-6passing.js 


    Store API 
express-session deprecated undefined resave option; provide resave option auth.j 
s:57:39 
express-session deprecated undefined saveUninitialized option; provide saveUnini 
tialized option auth.js:57:39 
    √ can load a Catagory by id (86ms) 
    √ can load all Catagories that have a certain parent (38ms) 
    √ can load a product by id 
    √ can load all products in a Catagory with sub-catagories 
    √ can load user cart 
error null 
    1) "before each" hook 


    5 passing (744ms) 
    1 failing 

    1) Store API "before each" hook: 
    Uncaught TypeError: Cannot read property 'data' of null 
     at test-6passing.js:243:17 
     at node_modules\mongoose\lib\query.js:1173:16 
     at node_modules\mongoose\node_modules\kareem\index.js:109:16 




D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore>mocha test-6passing.js 


    Store API 
express-session deprecated undefined resave option; provide resave option auth.j 
s:57:39 
express-session deprecated undefined saveUninitialized option; provide saveUnini 
tialized option auth.js:57:39 
    √ can load a Catagory by id (97ms) 
    √ can load all Catagories that have a certain parent (43ms) 
    √ can load a product by id 
    √ can load all products in a Catagory with sub-catagories 
    √ can load user cart 
error null 
    √ can save user cart 


    6 passing (785ms) 


D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore>mocha test-6passing.js 


    Store API 
express-session deprecated undefined resave option; provide resave option auth.j 
s:57:39 
express-session deprecated undefined saveUninitialized option; provide saveUnini 
tialized option auth.js:57:39 
    √ can load a Catagory by id (83ms) 
    √ can load all Catagories that have a certain parent 
    √ can load a product by id (39ms) 
    √ can load all products in a Catagory with sub-catagories 
    √ can load user cart 
error null 
    1) "before each" hook 


    5 passing (797ms) 
    1 failing 

    1) Store API "before each" hook: 
    Uncaught TypeError: Cannot read property 'data' of null 
     at test-6passing.js:243:17 
     at node_modules\mongoose\lib\query.js:1173:16 
     at node_modules\mongoose\node_modules\kareem\index.js:109:16 




D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore>mocha test-6passing.js 

D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore>mocha test-6passing.js 


    Store API 
express-session deprecated undefined resave option; provide resave option auth.j 
s:57:39 
express-session deprecated undefined saveUninitialized option; provide saveUnini 
tialized option auth.js:57:39 
    √ can load a Catagory by id (93ms) 
    √ can load all Catagories that have a certain parent (38ms) 
    √ can load a product by id 
    √ can load all products in a Catagory with sub-catagories 
    √ can load user cart 
error null 
    √ can save user cart 


    6 passing (806ms) 


D:\Programs_Insalled\nodejs\finalMEAN\edx\retailStore> 

於是問:

  1. 有沒有搞錯我做
  2. 是我的方法不正確
  3. 是否有摩卡的問題,我不知道
  4. 這是怎麼回事

我的環境是MongoDB中,節點,快速的Windows

編輯:完整的代碼可以在這裏找到:

https://github.com/shoaibhb/retailStore 

回答

2

這我不會打電話問題的解決方案,但它解決了我的問題。我改變了beforeEach()函數來分別處理創建和刪除數據之前,每個測試螞蟻它穩定它。

這是我所做的代碼。

beforeEach(function(done) { 
    // Make sure categories are empty before each test 
    Category.remove({}, function(error) { 
     assert.ifError(error); 
     Product.remove({}, function(error) { 
     assert.ifError(error); 
     User.remove({}, function(error) { 
      assert.ifError(error); 
      done(); 
     }); 
     }); 
    }); 
    }); 

    beforeEach(function(done) { 
    var categories = [ 
     { _id: 'Electronics' }, 
     { _id: 'Phones', 'parent': 'Electronics' }, 
     { _id: 'Laptops', 'parent': 'Electronics' }, 
     { _id: 'Bacon' } 
    ]; 

    var products = [ 
     { 
     name: 'LG G4', 
     category: { _id: 'Phones', ancestors: ['Electronics', 'Phones'] }, 
     price: { 
      amount: 300, 
      currency: 'USD' 
     } 
     }, 
     { 
     _id: PRODUCT_ID, 
     name: 'Asus Zenbook Prime', 
     category: { _id: 'Laptops', ancestors: ['Electronics', 'Laptops'] }, 
     price: { 
      amount: 2000, 
      currency: 'USD' 
     } 
     }, 
     { 
     name: 'Flying Pigs Farm Pasture Raised Pork Bacon', 
     category: { _id: 'Bacon', ancestors: ['Bacon'] }, 
     price: { 
      amount: 20, 
      currency: 'USD' 
     } 
     } 
    ]; 

    var users = [{ 
     profile: { 
     username: 'vkarpov15', 
     picture: 'http://pbs.twimg.com/profile_images/550304223036854272/Wwmwuh2t.png' 
     }, 
     data: { 
     oauth: 'invalid', 
     cart: [] 
     } 
    }]; 

    Category.create(categories, function(error) { 
     assert.ifError(error); 
     Product.create(products, function(error) { 
     assert.ifError(error); 
     User.create(users, function(error) { 
      assert.ifError(error); 
      done(); 
     }); 
     }); 
    }); 
    }); 
0

因此,這裏確實沒有足夠的信息,但我可以告訴你要查找什麼。讓我們先從你得到的錯誤:

Uncaught TypeError: Cannot read property 'data' of null 
    at test-6passing.js:243:17 
    at node_modules\mongoose\lib\query.js:1173:16 
    at node_modules\mongoose\node_modules\kareem\index.js:109:16 

因此,第二行告訴我們錯誤在測試6passing.js拋出,在配線243,列17.因此,遺憾的是,沒有按」 t顯示行號,所以我不知道確切的位置,但是您可以在文本編輯器中找到該行,並在錯誤發生時準確告訴您執行哪個函數。

第一行告訴我們您正在嘗試讀取對象的'data'屬性,但該對象是null。假設第243行的第17列的函數是Catagory.remove - 我們可以看看該函數,以確切知道測試中的對象是null。然後,你必須看爲什麼它是null

這有很多可能的原因。也許你拼錯了Catagory.remove函數中的對象名稱?也許信息尚未填充 - javascript是一種異步語言,對於來自其他編程語言的許多人來說很難習慣。

如果這沒有幫助,請嘗試使用定義模型及其方法/函數的代碼更新您的帖子。

+0

更新與鏈接到代碼的帖子。 – shoaibhb

0

看起來你的測試並不是每次都以相同的狀態離開數據庫。錯誤在這裏:

it('can load user cart', function(done) { 
    var url = URL_ROOT + '/me/'; 
    User.findOne({}, function(error, user) { 
     console.log("error %j",error); 
     //assert.ifError(error); 
     user.data.cart = [{ product: PRODUCT_ID, quantity: 1}]; 

其中user爲空。也許一些測試是刪除一個用戶,另一個是添加它?

+0

盡我所知,'beforeEach()'函數按順序執行,必須爲每個測試創建用戶。如果它不是由於任何原因而創建的,它應該聲明一個錯誤。事實並非如此。 – shoaibhb