10

पर एकमात्र पृष्ठ एप्लिकेशन जिस पर मैं काम कर रहा हूं, में दो रूपों के साथ लॉगिन दृश्य है: साइन-इन फॉर्म और साइन-अप फॉर्म। निम्नलिखित spec इन रूपों के लिए परीक्षण का वर्णन करता है। मैं Jasmine-jQuery 1.4.2..HaveBeenCalled का उपयोग कर जैस्मीन परीक्षण साइन-अप फॉर्म

// user_spec.js 

describe("User", function() { 

    var userController; 

    beforeEach(function() { 
    loadFixtures('menu.html'); 
    userController = new MyApp.User.Controller(); 
    }); 

    describe("LoginView", function() { 

    beforeEach(function() { 
     // Mock the $.ajax function to prevent XHR: 
     spyOn($, "ajax").andCallFake(function(params) {}); 
    }); 

    it("should pass email and password with the 'signInForm:submit' event.", function() { 
     var email = "[email protected]"; 
     var password = "Passw0rd"; 
     var callback = jasmine.createSpy("FormSubmitSpy"); 

     userController.loginView.$el.find("#signInEmail").val(email); 
     userController.loginView.$el.find("#signInPassword").val(password); 
     userController.loginView.bind("signInForm:submit", callback, this); 
     userController.loginView.ui.signInForm.trigger("submit"); 

     expect(callback).toHaveBeenCalledWith({ 
     email: email, 
     password: password 
     }); 
    }); 

    it("should pass name, email and password with the 'signUpForm:submit' event.", function() { 
     var name = "John Doe"; 
     var email = "[email protected]"; 
     var password = "Passw0rd"; 
     var callback = jasmine.createSpy("FormSubmitSpy"); 

     userController.loginView.$el.find("#signUpName").val(name); 
     userController.loginView.$el.find("#signUpMail").val(email); 
     userController.loginView.$el.find("#signUpPassword").val(password); 
     userController.loginView.$el.find("#signUpPasswordConfirmation").val(password); 
     userController.loginView.bind("signUpForm:submit", callback, this); 

     userController.loginView.ui.signUpForm.trigger("submit"); 

     expect(callback).toHaveBeenCalledWith({ 
     name: name, 
     email: email, 
     password: password, 
     password_confirmation: password 
     }); 
    }); 

    }); 

}); 

परीक्षण का उपयोग कर रहा साइन-इन फार्म के लिए सफल चलाता है तथापि साइन-अप फ़ॉर्म के लिए परीक्षण विफल रहता है।

Error: Expected spy FormSubmitSpy to have been called with \ 
    [ { name : 'John Doe', email : '[email protected]', \ 
    password : 'Passw0rd', password_confirmation : 'Passw0rd' } ] \ 
    but it was never called. 

    at new jasmine.ExpectationResult (http://localhost:3000/assets/jasmine.js?body=1:114:32) 
    at null.toHaveBeenCalledWith (http://localhost:3000/assets/jasmine.js?body=1:1235:29) 
    at null.<anonymous> (http://localhost:3000/assets/user_spec.js?body=1:233:24) 
    at jasmine.Block.execute (http://localhost:3000/assets/jasmine.js?body=1:1064:17) 
    at jasmine.Queue.next_ (http://localhost:3000/assets/jasmine.js?body=1:2096:31) 
    at jasmine.Queue.start (http://localhost:3000/assets/jasmine.js?body=1:2049:8) 
    at jasmine.Spec.execute (http://localhost:3000/assets/jasmine.js?body=1:2376:14) 
    at jasmine.Queue.next_ (http://localhost:3000/assets/jasmine.js?body=1:2096:31) 
    at jasmine.Queue.start (http://localhost:3000/assets/jasmine.js?body=1:2049:8) 
    at jasmine.Suite.execute (http://localhost:3000/assets/jasmine.js?body=1:2521:14) 

आवेदन में फॉर्मों का उपयोग करने में कोई समस्या नहीं है। डेटा प्रसारित किया जाता है। सब कुछ ठीक काम करता है। बस परीक्षण नहीं करता है।

वर्कअराउंड

परीक्षण तथापि सफल है जब मैं इसके निष्पादन में देरी।

_.defer(function() { 
    expect(callback).toHaveBeenCalledWith({ 
    name: name, 
    email: email, 
    password: password, 
    password_confirmation: password 
    }); 
}); 

यह काम क्यों करता है और "सामान्य" कार्यान्वयन विफल रहता है?

it("should evaluate true", function() { 
    var foo = false; 
    _.defer(function() { 
    foo = true; 
    }); 
    expect(foo).toBeTruthy(); 
}); 
+0

यदि आप साइनइनफॉर्म परीक्षण को हटाते हैं तो क्या होता है? या साइनअपफॉर्म परीक्षण के बाद इसे ले जाएं? –

+0

शायद कुछ और घटना रोक रहा है और फिर कुछ कार्रवाई के बाद retriggering। ऐसा प्रपत्र प्रस्तुत करने में कुछ हद तक लगता है जो पृष्ठ को रीफ्रेश नहीं करना चाहिए। अगर स्टॉपर तुल्यकालिक रूप से ट्रिगर नहीं करता है, तो यह जासूस असफल हो जाएगा। – fncomp

उत्तर

1

शायद jQuery बाँध और चमेली के जासूस सीधे से अधिक लपेटता क्योंकि कॉलबैक, किसी अन्य विधि में नीडिंत है कारण है कि आप इस समस्या को देख रहे हैं जाता है:


यहाँ दिए गए मामले का सरलीकरण है आपकी विधि इसलिए जब परीक्षण स्थापित होता है तो आपकी विधि अगले टिक तक निष्पादित नहीं होती है।

मुझे यह पृष्ठ मिला: http://trevmex.com/post/7017702464/nesting-spies-to-see-if-a-callback-in-a-deep-nest-has उपयोगी है क्योंकि यह आपकी समस्या का वर्णन करता है और एक संभावित कार्य करता है।

हालांकि मुझे पता चला है कि यह कॉलबैक की जांच करने के लिए सबसे अच्छा नहीं है क्योंकि उन्हें निजी तरीके माना जा सकता है। शायद आप इसके अंतिम परिणाम का परीक्षण कर सकते हैं?

2

जैस्मीन स्थगन के लिए एक अंडरस्कोर समारोह का उपयोग किए बिना एक ही बात करने के लिए किया जाएगा निम्नलिखित तरीके:

var flag = false; 
... 

runs(function() { 
    userController.loginView.ui.signInForm.trigger("submit"); 
    setTimeout(function() { flag = true; }, 1); 
} 

waitsFor(function() { 
    return flag; 
}, "Blah this should never happen", 10); 

runs(function() { 
    expect(callback).toHaveBeenCalledWith({ 
    name: name, 
    email: email, 
    password: password, 
    password_confirmation: password 
    }); 
} 

@Marc सही है कि इस मुद्दे को बाँध और जिस तरह जावास्क्रिप्ट भेजता घटनाओं "कभी कभी उपयोग करने के साथ है/आमतौर पर/हमेशा "वह अगले कार्यक्रम लूप में (इसकी असीमित प्रकृति कैसे काम करती है), इसलिए जब आप कॉलबैक पर जासूसी कर रहे हैं तो आप यह सुनिश्चित करना चाहते हैं कि आपके परीक्षण उस अतुल्यकालिक व्यवहार के लिए खाते में लिखे गए हों।

जैसा कि आपके परीक्षण लिखे गए हैं, आप जोखिम को चलाते हैं कि पहला परीक्षण या तो स्पोरैडिक रूप से पारित नहीं होगा (मुझे आश्चर्य है कि यह काम करता है)। आप एक असीमित घटना कॉलबैक का परीक्षण एक गैर असीमित फैशन में कर रहे हैं ... समझ में आता है?

संबंधित मुद्दे