小さな ember.js アプリを既存の Web サイトに統合しようとしています。コードは問題なく動作しますが、統合テストが機能しません。
メッセージング.js
window.App = Ember.Application.create();
App.Store = DS.Store.extend({
revision: 12,
adapter: 'DS.FixtureAdapter'
});
App.Router.map(function () {
this.resource('index', {path: '/'}, function () {
this.resource('detail', {path: ':message_id'});
});
});
App.IndexRoute = Ember.Route.extend({
model: function () {
return App.MessageSummary.find();
},
events: {
select: function (summary) {
this.transitionTo('detail', App.Message.find(summary.get('id')));
}
}
});
App.MessageSummary = DS.Model.extend({
id: DS.attr('string'),
date: DS.attr('string'),
status: DS.attr('string'),
by: DS.attr('string'),
subject: DS.attr('string')
});
App.Message = DS.Model.extend({
id: DS.attr('string'),
subject: DS.attr('string')
});
App.MessageSummary.FIXTURES = [
{id: '1', date: '04/19/2013 8:15 PM', status: 'read', by: 'your doctor', subject: 'Your heart attack'},
{id: '2', date: '04/19/2013 8:15 PM', status: 'read', by: 'your doctor', subject: 'Your heart attack'},
{id: '3', date: '04/19/2013 8:15 PM', status: 'read', by: 'your doctor', subject: 'Your heart attack'},
{id: '4', date: '04/19/2013 8:15 PM', status: 'read', by: 'your doctor', subject: 'Your heart attack'},
{id: '5', date: '04/19/2013 8:15 PM', status: 'read', by: 'your doctor', subject: 'Your heart attack'}
];
App.Message.FIXTURES = [
{id: '1', subject: 'Your heart attack (Detail 1)'},
{id: '2', subject: 'Your heart attack (Detail 2)'},
{id: '3', subject: 'Your heart attack (Detail 3)'},
{id: '4', subject: 'Your heart attack (Detail 4)'},
{id: '5', subject: 'Your heart attack (Detail 5)'}
];
メッセージング.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<script type="text/javascript" src="js/lib/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="js/lib/handlebars-1.0.0-rc.3.js"></script>
<script type="text/javascript" src="js/lib/ember-1.0.0-rc.3.js"></script>
<script type="text/javascript" src="js/lib/ember-data-latest.min.js"></script>
<script type="text/javascript" src="js/messaging.js"></script>
<title>Messaging</title>
</head>
<body>
<script type="text/x-handlebars" id="index">
<div>
<table class="rounded-corner summary">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Status</th>
<th scope="col">From</th>
<th scope="col">Subject</th>
</tr>
</thead>
<tbody>
{{#each model}}
<tr {{action select this}}>
<td>{{date}}</td>
<td>{{status}}</td>
<td>{{by}}</td>
<td>{{subject}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div>
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" id="detail">
<div>
{{id}}: {{subject}}
</div>
</script>
</body>
</html>
ご覧のとおり、かなり些細なことです。ブラウザで魅力的に機能します。Ember が非常に独断的で、設定より規約を優先するフレームワークであることを考えると、統合テストは正しい方法のようです。したがって、既存のツールを使用しようとすると、私の jsTestDriver 単体テストは次のようになります。
jsTestDriver.conf:
server: http://localhost:9876
load:
- src/main/webapp/js/lib/jquery-1.8.3.min.js
- src/main/webapp/js/lib/handlebars-1.0.0-rc.3.js
- src/main/webapp/js/lib/ember-1.0.0-rc.3.js
- src/main/webapp/js/lib/ember-data-latest.min.js
- src/test/webapp/js/emberTesting.js
- src/main/webapp/js/messaging.js
- src/test/webapp/js/jshamcrest-0.6.7.min.js
- src/test/webapp/js/jsmockito-1.0.4-minified.js
test:
- src/test/webapp/js/messagingTests.js
メッセージングTests.js
JsHamcrest.Integration.JsTestDriver();
JsMockito.Integration.JsTestDriver();
App.Router.reopen({
location: 'none'
});
jQuery.fx.off = true;
TestCase('secure messaging integration tests', {
setUp: function () {
/*:DOC +=
<script type="text/x-handlebars" id="index">
<div>
<table class="rounded-corner summary">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Status</th>
<th scope="col">From</th>
<th scope="col">Subject</th>
</tr>
</thead>
<tbody>
{{#each model}}
<tr {{action select this}}>
<td>{{date}}</td>
<td>{{status}}</td>
<td>{{by}}</td>
<td>{{subject}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div>
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" id="detail">
<div>
{{id}}: {{subject}}
</div>
</script>
*/
Ember.run(function () {
if (App.store) App.store.destroy();
App.store = App.Store.create();
});
App.reset();
},
'test initial load loads table body': function () {
console.log($('body').html());//debug
assertThat($('.summary tbody tr').length, equalTo(5));
}
});
テストの実行中に、ember.js は例外をスローします。
ブラウザのコンソール出力:
DEBUG: -------------------------------
ember-1.0.0-rc.3.js:349DEBUG: Ember.VERSION : 1.0.0-rc.3
ember-1.0.0-rc.3.js:349DEBUG: Handlebars.VERSION : 1.0.0-rc.3
ember-1.0.0-rc.3.js:349DEBUG: jQuery.VERSION : 1.8.3
ember-1.0.0-rc.3.js:349DEBUG: -------------------------------
ember-1.0.0-rc.3.js:18334Error: Cannot perform operations on a Metamorph that is not in the DOM.
エラーがスローされた時点のスタックのトップは次のとおりです。
checkRemoved(18334)
html(18304)
empty(19077)
empty(16899)
arrayWillChange(17700)
sendEvent(2432)
arrayContentWillChange(8909)
arrangedContentArrayWillChange(11578)
sendEvent(2432)
arrayContentWillChange(8909)
replace(12007)
insertAt(9411)
pushObject(9464)
addObject(9619)
レンダリングされた html の本文は次のとおりです。
<div id="ember407" class="ember-view">
<div>
<table class="rounded-corner summary">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Status</th>
<th scope="col">From</th>
<th scope="col">Subject</th>
</tr>
</thead>
<tbody>
<script id="metamorph-0-start" type="text/x-placeholder"></script><script id="metamorph-0-end" type="text/x-placeholder"></script>
</tbody>
</table>
</div>
<div>
<script id="metamorph-1-start" type="text/x-placeholder"></script><script id="metamorph-1-end" type="text/x-placeholder"></script>
</div>
</div>
ember.js のバインディングが機能する方法を考えると、jsTestDriver の AsyncTestCase を使用する必要があるかもしれませんが、ember はレンダリング中に例外をスローするため、最初にその問題を解決する必要があります。
アイデア?