问题
I am trying to test my backbone views with jasmine. I use underscore library to generate templates for the backbone views.
For testing purposes I use jasmine jasmine-jquery
I am unable to load the fixtures in the jasmine tests as the views have embeded ruby. Here is my code
Backbone view
AlbumView = Backbone.View.extend({
template: _.template($('#album-template').html()),
render: function() {
$('#albums').append(this.template(this.model.attributes));
}
});
This view uses the following template
Album template album_template.html.erb
<script type="text/html" id="album-template">
<a href="<%%= url %>" class="album <%%= is_owner %>">
<%% if (viewable) { %>
<span class="album-cover">
<span class="photo" style="background-image:url('<%%= small_thumbnail_url %>'); width: 160px; height: 160px;">
<span class="glossy-overlay"></span>
</span>
</span>
<%% } %>
<h3><%%= name %></h3>
<p>
<%%= number_of_photos %>
</p>
</a>
</script>
Backbone model
var Album = Backbone.Model.extend({
initialize: function() {
this.view = new AlbumView({model: this});
},
render: function() {
this.view.render();
}
});
Jasmine test - album_spec.js
describe('Album view', function(){
beforeEach(function() {
var album = new Album({
"name": "Photo Stream",
"url": "/albums/1",
"id": "2",
"number_of_photos": "172 Photos",
"small_thumbnail_url": "/assets/sections/albums/covers/auto.png",
"viewable": true,
"is_owner": "owner"
});
loadFixtures('albums_fixture.html');
this.view = new AlbumView();
this.view.model = album;
// loadFixtures('albums_fixture.html');
});
describe("Rendering", function() {
it ("produces the correct HTML", function() {
this.view.render();
expect($("#albums")).toExist();
expect(this.view.template).toBeDefined();
});
});
});
This spec loads the following fixture - album_fixture.html
<div id="albums"> </div>
<script type="text/html" id="album-template">
<a href="<%%= url %>" class="album <%%= is_owner %>">
<%% if (viewable) { %>
<span class="album-cover">
<span class="photo" style="background-image:url('<%%= small_thumbnail_url %>'); width: 160px; height: 160px;">
<span class="glossy-overlay"></span>
</span>
</span>
<%% } %>
<h3><%%= name %></h3>
<p>
<%%= number_of_photos %>
</p>
</a>
</script>
This test is failing at
expect(this.view.template).toBeDefined();
The fixtures is loading as this test passes expect($("#albums")).toExist();
My question is how can I load fixtures that have views with embedded ruby? I was able to successfully test the models and collections but I am having trouble testing the views.
回答1:
This line:
template: _.template($('#album-template').html())
in your AlbumView
is going to be executed when that script file is loaded into the page. Since the fixture doesn't get added to the page until the spec starts to execute, the album-template
script tag hasn't been added to the DOM yet.
If you rewrote your template
attribute to be a method that returned the result of calling _.template
then it wouldn't look for the script tag until you actually tried to invoke the template. This could look something like:
AlbumView = Backbone.View.extend({
template: function() {
return _.template($('#album-template').html());
},
render: function() {
$('#albums').append(this.template()(this.model.attributes));
}
});
Granted, this is kinda gross. The other option would be to set up the underscore template as an asset served by the asset pipeline and have jasmine-gem include it into the page before you load your views.
来源:https://stackoverflow.com/questions/12736727/testing-backbone-views-with-jasmine