Vue.js - Testing asynchronously returned data

I have the following example:

<!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 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> 

I want to verify that Vue is receiving data from the server asynchronously. Although, I make fun of the actual http request with Sinon FakeServer.

Naturally, immediately after calling loadMessage message has not yet been set. I could use the timeout function for the test, but I believe there should be a better method. I looked at respondImmediately , but that has not changed. In addition, it is possible to call the done () function. However, as I understand it, this would have to be called in the loadMessage function, therefore, modifying the code under test.

What is the right approach to solve this problem?

Edit: I found at least a partial solution, but it seems to be still messy: call the done () function in the mocha unit test. When a statement fails, it is at least shown in the html output. However, the approval message is not as clear as in a regular test. In addition, the technique seems to me still dirty.

+5
source share
1 answer

Since updating the vue component is asynchronous, you will need to use

 // 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() }) }) 

It is taken from official documents .

+1
source

Source: https://habr.com/ru/post/1259497/


All Articles