2016-11-09 100 views
5

我下面舉個例子:Vue.js - 異步測試返回的數據

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Mocha</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <link rel="stylesheet" href="mocha.css" /> 
    </head> 
    <body> 
    <div id="mocha"></div> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.1.2/mocha.min.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.min.js"></script> 

    <script src="https://unpkg.com/vue/dist/vue.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/1.0.3/vue-resource.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/1.15.4/sinon.js"></script> 

    <script>mocha.setup('bdd');</script> 
    <script> 
    "use strict"; 
    var assert = chai.assert; 
    var should = chai.should(); 

    var vm = new Vue({ 
    data: { 
     message: "Hello" 
    }, 

    methods: { 
     loadMessage: function() { 
     this.$http.get("/get").then(
      function(value) { 
      this.message = value.body.message; 
      }); 
     }, 
    } 
    }); 
    describe('getMessage', function() { 
    let server; 
    beforeEach(function() { 
     server = sinon.fakeServer.create(); 
    }); 

    it("should get the message", function(done) { 
     server.respondWith([200, { 'Content-Type': 'application/json' }, 
       JSON.stringify({message: "Test"})]); 

     vm.message.should.equal("Hello"); 
     vm.loadMessage(); 
     server.respond(); 
     setTimeout(function() { 
     // This one works, but it's quirky and a possible error is not well represented in the HTML output. 
     vm.message.should.equal("Test"); 
     done(); 
     }, 100); 

     // This one doesn't work 
     //vm.message.should.equal("Test"); 
    }); 
    }); 
    </script> 
    <script> 
     mocha.run(); 
    </script> 
    </body> 
</html> 

我想測試的Vue異步從服務器獲取數據。雖然,我用Sinon FakeServer嘲笑了實際的http請求。

當然,直接調用loadMessage之後,消息還沒有設置。我可以使用超時功能進行測試,但我相信應該有更好的方法。我已經看過respondImmediately,但它沒有改變。此外,還有可能調用done()函數。然而,據我所知,這樣做需要在loadMessage函數中調用,因此修改了測試中的代碼。

解決此問題的正確方法是什麼?

編輯:我發現至少有部分解決方案,但它似乎仍然凌亂:在摩卡單元測試中調用done()函數。當斷言失敗時,它至少顯示在html輸出中。然而,斷言信息並不像在正常測試中那樣清晰。另外,這個技術對我來說似乎還是很混亂。

+0

如果你沒有得到更好的答案,你應該看看攔截器:https://github.com/pagekit/vue-resource/blob/master/docs/http.md#interceptors – Hammerbot

+0

loadMessage返回什麼? –

+0

loadMessage不返回任何內容,並在視圖模型中定義。它從服務器異步加載數據,並在接收到消息時更新模型。 –

回答

1

由於VUE組件的更新是異步完成的,你需要使用

// Inspect the generated HTML after a state update 
    it('updates the rendered message when vm.message updates', done => { 
    const vm = new Vue(MyComponent).$mount() 
    vm.message = 'foo' 
    // wait a "tick" after state change before asserting DOM updates 
    Vue.nextTick(() => { 
     expect(vm.$el.textContent).toBe('foo') 
     done() 
    }) 
    }) 

official docs服用。