2012-08-09 14 views
17

Diyelim ki, basitlik adına (gerçek şey karmaşık ve alakasız), mevcut pencerenin sorgulama değerini döndüren bir yardımcı işlevim var. (Test koşum alakalı olup olmadığını emin değilim)qUnit sınaması için window.location nesnesini kullanmak mümkün mü?

var someUtilityFunction =() { 
    return window.location.search.substring(1); 
}; 

Şimdi birim test qUnit bu işlevi istiyorum:

test('#1 someUtilityFunction works', function() { 
    // setup 
    var oldQS = window.location.search; 
    window.location.search = '?key1=value1&key2=value2&key3=value3'; 

    var expectedOutput = 'key1=value1&key2=value2&key3=value3'; 

    // test 
    equals(someUtilityFunction(), 
     expectedOutput, 
     'someUtilityFunction works as expected.'); 

    // teardown 
    window.location.search = oldQS; 
}); 

Buradaki sorun, farklı bir sorgu dizesi için window.location.search ayardır ki Sayfanın yeniden yüklenmesine neden olmak, aslında sonsuz bir istek döngüsüne girmek. olmadan window.location nesnesini someUtilityFunction işlevinde herhangi bir değişiklik yapmadan çözmek için herhangi bir yol var mı?

cevap

18

Birkaç gün önce aynı sorunla karşılaştık.

kodunuzu

Bu çözüm (varsa) en iyi olmayabilir, ama daha kolay alay yapmak için fonksiyona window nesneyi geçirmeden dikkate olmayabilir yeniden yazma

: Ağırlıklı olarak 2 yaklaşım vardır. Daha da iyisi, bir kapatma kullanın ve kodunuzu kapsülleyin.
  • Sen
  • Sen çarpışmalar
  • gölgeleme gerçekten kolay alay yapar adlandırma önleyebilirsiniz özel yerel değişkenler kullanabilirsiniz, sadece başka bir şey geçmek

    • Sen gölge global değişkenler: Bu birkaç avantajı vardır

    Sen alay bir işlev içindeki tüm kodunuzu sarabilirsiniz kodunuzu sarın Pencere nesnesini yerel bir değişkene dönüştürür. Sen de orada temelde iki ihtimal vardır:

    bu sahte olduğunu varsayalım:

    var customWindow = { 
        location: { 
         search: "", 
         hash: "" 
        } 
    }; 
    

    bir kapatma Bu, yerel window ile küresel window gölgeler

    var someUtilityFunction; 
    
    (function(window) { 
        // window is now shadowed by your local variable 
        someUtilityFunction =() { 
         return window.location.search.substring(1); 
        }; 
    })(customWindow); 
    

    kullanın. Birlikte karşı genellikle şiddetle olmama rağmen

    gerçekten burada sorunların çoğunu çözebilir, with deyimi

    kullanın. Temel olarak kapsamınızı düzelttiğinden, ortamınızı çok rahatça yapabilirsiniz. Bu arada

    // first some more preparation for our mock 
    customWindow.window = customWindow; 
    
    with(customWindow) { 
    
        // this still creates the var in the global scope 
        var someUtilityFunction =() { 
         // window is a property of customWindow 
         return window.location.search.substring(1); 
        }; 
    
        // since customWindow is our scope now 
        // this will work also 
        someUtilityFunction =() { 
         // location is a property of customWindow too 
         return location.search.substring(1); 
        }; 
    
    } 
    

    : search mülkiyet hash özelliğiyle aynı semptomlardan muzdarip eğer bilmiyorum - yani bazen soru işareti dahil ve bazen değil.Ama ben window.history.pushState kullanarak bazı başarı elde ettik

    window.location.search.replace(/^\?/, ""); 
    

    yerine

    window.location.substr(1); 
    
  • +0

    teşekkürler. Kodun yeniden yazılması, 'window' nesnesini isteğe bağlı olarak aldığından yardımcı olmaz - bu durum, biri geçilmediğinde test edilir. Bir "sahte blok" içinde işlevi sarma işlevi yapmak zorunda olabileceğimi göründüğü işlevdeki kodu değiştiriyor olabilir. – jbabey

    +0

    Kodunuzu yeniden yazmamak için kodunuzu bir şekilde sarmanız gerekir. Ben de iyi çalışıyor bir 'with' sarmalayıcı çalıştı (ancak yanlış kullanarak bunu kullanıyor). Daha sonra, özel 'window' nesnesini, özelliklerinizi taklit etmek ve kodunuzda ve ayrıca testte de kullanılabilir hale getirmek için global olarak kullanılabilir hale getirebilirsiniz. Sanırım jQuery ve Zepto da 'window' ve 'document' paketleyicilerine de geçtikleri için bunu yapıyorlar. –

    1

    kullanarak düşünebilirsiniz. Bakınız this StackOverflow answer. Aksi Sen sorgu dize olacaktır,

    function setQueryString(queryString) { 
        window.history.pushState({}, '', '?' + queryString); 
    } 
    

    Sen QUnit.module ait afterEach yöntemi ile sorgu dizesi temizlemek gerekir: her birim test için, ben o zaman böyle uygulamak bir işlevi setQueryString('var=something') çağırmak Son testin değerine ayarladığınızda, garip sonuçlar elde edersiniz. cevap için

    +0

    Benim için çalışmıyor. Yaparsam bir '' window.history.pushState (...); '' ve bana Qunit-html sayfanın geçerli URL'sini verir '' doğrudan '' console.log (window.location) ile kontrol edin. Örnek kodunuz var mı? – jerik

    İlgili konular