Saya memiliki arahan AngularJS yang memiliki templateUrl
definisi. Saya mencoba untuk mengujinya dengan Jasmine.
JavaScript Jasmine saya terlihat seperti berikut, sesuai rekomendasi ini :
describe('module: my.module', function () {
beforeEach(module('my.module'));
describe('my-directive directive', function () {
var scope, $compile;
beforeEach(inject(function (_$rootScope_, _$compile_, $injector) {
scope = _$rootScope_;
$compile = _$compile_;
$httpBackend = $injector.get('$httpBackend');
$httpBackend.whenGET('path/to/template.html').passThrough();
}));
describe('test', function () {
var element;
beforeEach(function () {
element = $compile(
'<my-directive></my-directive>')(scope);
angular.element(document.body).append(element);
});
afterEach(function () {
element.remove();
});
it('test', function () {
expect(element.html()).toBe('asdf');
});
});
});
});
Ketika saya menjalankan ini dalam kesalahan spesifikasi Jasmine saya, saya mendapatkan kesalahan berikut:
TypeError: Object #<Object> has no method 'passThrough'
Yang saya inginkan adalah templateUrl dimuat apa adanya - saya tidak ingin menggunakan respond
. Saya yakin ini mungkin terkait dengan penggunaan ngMock daripada ngMockE2E . Jika ini pelakunya, bagaimana cara menggunakan yang terakhir daripada yang pertama?
Terima kasih sebelumnya!
.passThrough();
dengan cara itu, tetapi dari dokumen, apakah Anda sudah mencoba sesuatu seperti:$httpBackend.expectGET('path/to/template.html'); // do action here $httpBackend.flush();
Saya rasa ini lebih cocok dengan penggunaan Anda - Anda tidak ingin menangkap permintaan, yaituwhenGet()
, tetapi memeriksa apakah sudah terkirim, dan kemudian sebenarnya Kirimkan?expectGET
mengirimkan permintaan ... setidaknya di luar kotak. Di dokumen, contoh mereka dengan/auth.py
memiliki$httpBackend.when
sebelum$httpBackend.expectGET
dan$httpBackend.flush
panggilan.expectGet
hanya memeriksa apakah suatu permintaan telah dicoba.$httpBackend
tiruan untuk benar-benar menggunakan URL yang disediakan di arahan di bawahtemplateUrl
dan mendapatkannya. Saya pikirpassThrough
akan melakukan ini. Apakah Anda mengetahui cara lain untuk melakukan ini?Jawaban:
Anda benar bahwa ini terkait dengan ngMock. Modul ngMock dimuat secara otomatis untuk setiap pengujian Angular, dan menginisialisasi tiruan
$httpBackend
untuk menangani setiap penggunaan$http
layanan, yang mencakup pengambilan template. Sistem template mencoba untuk memuat template$http
dan itu menjadi "permintaan tak terduga" untuk tiruan.Apa yang Anda perlukan cara untuk memuat template ke dalam
$templateCache
sehingga sudah tersedia saat Angular memintanya, tanpa menggunakan$http
.Solusi Pilihan: Karma
Jika Anda menggunakan Karma untuk menjalankan pengujian Anda (dan memang seharusnya demikian), Anda dapat mengkonfigurasinya untuk memuat template untuk Anda dengan preprocessor ng-html2js . Ng-html2js membaca file HTML yang Anda tentukan dan mengubahnya menjadi modul Angular yang memuat file
$templateCache
.Langkah 1: Aktifkan dan konfigurasikan preprocessor di file
karma.conf.js
Jika Anda menggunakan Yeoman untuk membuat perancah aplikasi Anda, konfigurasi ini akan berfungsi
Langkah 2: Gunakan modul dalam pengujian Anda
Untuk contoh lengkap, lihat contoh kanonik ini dari guru tes Angular Vojta Jina . Ini mencakup seluruh pengaturan: konfigurasi karma, templat, dan tes.
Solusi Non-Karma
Jika Anda tidak menggunakan Karma karena alasan apa pun (saya memiliki proses pembuatan yang tidak fleksibel di aplikasi lama) dan hanya menguji di browser, saya telah menemukan bahwa Anda dapat mengatasi pengambilalihan ngMock
$httpBackend
dengan menggunakan XHR mentah untuk mengambil template secara nyata. dan masukkan ke dalam$templateCache
. Solusi ini kurang fleksibel, tetapi menyelesaikan pekerjaan untuk saat ini.Serius, sih. Gunakan Karma . Dibutuhkan sedikit kerja untuk menyiapkan, tetapi ini memungkinkan Anda menjalankan semua pengujian Anda, di beberapa browser sekaligus, dari baris perintah. Jadi Anda dapat memilikinya sebagai bagian dari sistem integrasi berkelanjutan Anda, dan / atau Anda dapat menjadikannya tombol pintas dari editor Anda. Jauh lebih baik daripada alt-tab-refresh-ad-infinitum.
sumber
preprocessors
pola file (misalnya"path/to/templates/**/*.html"
) kefiles
bagian dalamkarma.conf.js
.false
parameter untukopen
panggilan XHR untuk membuatnya sinkron. Jika Anda tidak melakukannya, eksekusi akan terus berlanjut dan mulai menjalankan pengujian Anda, tanpa memuat template. Itu membuat hak Anda kembali ke masalah yang sama: 1) Permintaan template keluar. 2) Tes mulai dijalankan. 3) Tes mengkompilasi direktif, dan template masih belum dimuat. 4) Angular meminta template melalui$http
layanannya, yang diejek. 5) Layanan tiruan$http
mengeluh: "permintaan tak terduga".npm install --save-dev karma-ng-html2js-preprocessor
), dan menambahkannya ke bagian plugin Andakarma.conf.js
, menurut stackoverflow.com/a/19077966/859631 .Apa yang akhirnya saya lakukan adalah mendapatkan cache template dan meletakkan tampilan di sana. Saya tidak memiliki kendali atas tidak menggunakan ngMock, ternyata:
sumber
Masalah awal ini dapat diselesaikan dengan menambahkan ini:
Itu karena mencoba menemukan $ httpBackend di modul ngMock secara default dan tidak penuh.
sumber
Solusi yang saya capai membutuhkan jasmine-jquery.js dan server proxy.
Saya mengikuti langkah-langkah ini:
tambahkan jasmine-jquery.js ke file Anda
tambahkan server proxy yang akan melayani perlengkapan Anda
Dalam spesifikasi Anda
deskripsikan ('MySpec', function () {var $ scope, template; jasmine.getFixtures (). fixturesPath = 'public / partials /'; // jalur kustom sehingga Anda dapat menyajikan template sebenarnya yang Anda gunakan di aplikasi beforeEach (function () {template = angular.element ('');
});
Jalankan server di direktori root aplikasi Anda
python -m SimpleHTTPServer 3502
Jalankan karma.
Butuh beberapa saat untuk mengetahuinya, karena harus mencari banyak posting, saya pikir dokumentasi tentang ini harus lebih jelas, karena ini adalah masalah yang sangat penting.
sumber
localhost/base/specs
dan menambahkan server proxy denganpython -m SimpleHTTPServer 3502
menjalankan perbaikannya. Anda tuan adalah seorang jenius!Solusi saya:
test/karma-utils.js
:karma.config.js
:ujian:
sumber
static
, misalnyabeforeEach(preloadTemplate(static_url +'seed/partials/beChartDropdown.html'));
Terima kasih!Jika Anda menggunakan Grunt, Anda dapat menggunakan grunt-angular-templates. Ini memuat template Anda di templateCache dan transparan dengan konfigurasi spesifikasi Anda.
Contoh konfigurasi saya:
sumber
Saya memecahkan masalah yang sama dengan cara yang sedikit berbeda dari solusi yang dipilih.
Pertama, saya menginstal dan mengkonfigurasi plugin ng-html2js untuk karma. Di file karma.conf.js:
Lalu saya memuat modul yang dibuat di beforeEach. Di file Spec.js Anda:
Lalu saya menggunakan $ templateCache.get untuk menyimpannya ke dalam variabel. Di file Spec.js Anda:
Akhirnya saya mengujinya dengan cara ini. Di file Spec.js Anda:
sumber
Untuk memuat html template secara dinamis ke $ templateCache Anda bisa menggunakan pra-prosesor karma html2js, seperti yang dijelaskan di sini
intinya adalah menambahkan template ' .html' ke file Anda di file conf.js juga preprocessors = {' .html': 'html2js'};
dan gunakan
ke dalam file pengujian js Anda
sumber
Uncaught SyntaxError: Unexpected token <
jika Anda menggunakan Karma, pertimbangkan untuk menggunakan karma-ng-html2js-preprocessor untuk melakukan pra-kompilasi template HTML eksternal Anda dan hindari Angular mencoba HTTP GET selama eksekusi pengujian. Saya berjuang dengan ini untuk beberapa milik kami - dalam kasus saya, jalur parsial templateUrl diselesaikan selama eksekusi aplikasi normal tetapi tidak selama pengujian - karena perbedaan dalam struktur app vs. test dir.
sumber
Jika Anda menggunakan plugin jasmine-maven bersama - sama dengan RequireJS, Anda dapat menggunakan plugin teks untuk memuat konten template ke dalam variabel, lalu meletakkannya di cache template.
sumber
Jika Anda menggunakan requirejs dalam pengujian Anda, maka Anda dapat menggunakan plugin 'text' untuk menarik template html dan meletakkannya di $ templateCache.
sumber
Saya menyelesaikan masalah ini dengan menyusun semua template ke templatecache. Saya menggunakan teguk, Anda dapat menemukan solusi serupa untuk mendengus juga. TemplateUrls saya dalam direktif, modals terlihat seperti
Tambahkan paket npm baru di my package.json
"gulp-angular-templatecache": "1.*"
Di file gulp tambahkan templatecache dan tugas baru:
var templateCache = require('gulp-angular-templatecache'); ... ... gulp.task('compileTemplates', function () { gulp.src([ './app/templates/**/*.html' ]).pipe(templateCache('templates.js', { transformUrl: function (url) { return '/templates/' + url; } })) .pipe(gulp.dest('wwwroot/assets/js')); });
Tambahkan semua file js di index.html
<script src="/assets/js/lib.js"></script> <script src="/assets/js/app.js"></script> <script src="/assets/js/templates.js"></script>
Nikmati!
sumber