6

What is the simplest way to modify scenarios.js to mock an AJAX request during an end-to-end test?

<!doctype html>
<html lang="en" ng-app="myApp">
<head>
  <meta charset="utf-8">
  <title>My Test AngularJS App</title>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular-resource.min.js"></script>

  <script language="javascript" type="text/javascript">
      angular.module('myApp', ['ngResource']);
      function PlayerController($scope,$resource){
        $scope.player = $resource('player.json').get();
      }
    </script>

</head>
  <body ng-controller="PlayerController">
    <p>Hello {{player.name}}</p>
  </body>
</html>

Player gets correctly fetched from a file named player.json on the server and the following test passes. How do I pass different json in to this test and prevent the fetch back to the server?

/*
How do I pass in
player.json -> {"name":"Chris"}
*/
describe('my app', function() {

  beforeEach(function() {
    browser().navigateTo('../../app/index.html');
  });

  it('should load player from player.json', function() {
    expect(element('p:first').text()).
        toMatch("Hello Chris");
    pause();
  });

});
Sami N
  • 1,170
  • 2
  • 9
  • 21
Chris
  • 4,237
  • 6
  • 30
  • 42

3 Answers3

4

You should use $httpBackend from ngMockE2E module to mock http requests. Take a look at the docs.

Caio Cunha
  • 23,326
  • 6
  • 78
  • 74
  • 3
    My point is that I don't see the ngMockE2E example in the docs. I'm looking for the few lines of code to add to scenarios.js. – Chris Dec 17 '12 at 23:59
  • You shouldn't need to mod scenario.js if I'm understanding your question correctly. Caio's answer is the standard way to handle this situation – Roy Truelove Dec 18 '12 at 13:53
  • 3
    Ok. Let me be clear. I don't understand how to do what Caio is recommending. There is some magic that is being assumed by the documentation such as "Afterwards, bootstrap your app with this new module.". How does one do that? – Chris Dec 18 '12 at 14:13
  • 2
    To be clear, what file does the ngMockE2E code go into? How does the runner.html or scenarios.js file need to be modified for the magic to happen? – Chris Dec 18 '12 at 14:20
  • The docs says that `you have to create a module that depends on the ngMockE2E`: `angular.module('myApp', 'ngMockE2E']);`. You gonna need to include angular-mocks.js so it works. If i'm not wrong (I wish I am), seems you can't mock it at the scenario. But saw some discutions around it [here](https://groups.google.com/forum/#!msg/angular/AY_eom9X_zA/lVaQAXdmg9UJ) and [here](https://groups.google.com/forum/?fromgroups=#!topic/angular/hkay_BrD9Vk). – Caio Cunha Dec 19 '12 at 12:44
1

It appears that currently you can not ONLY modify scenarios.js to include $httpBackend mocking. You will have to add some other code to support it.

For me the best way seems to be the following

Add a myAppTest.js in your test folder that includes 'ngMockE2E' so you don't need to pollute your existing app.js

'use strict';

angular.module('myAppTest', ['myApp', 'ngMockE2E'])
.run(function($httpBackend) {
    var user = {name: 'Sandra'};
    $httpBackend.whenGET('/api/user').respond(user); 
});

Then add a separate test-index.html that uses the new myAppTest.js. Note you need to include angular-mocks.js. (This leaves your production html file intact and free of mocks)

<!doctype html>
<html lang="en" ng-app="myAppTest">
<head>
  <script src="lib/angular/angular.js"></script>
  <script src="lib/angular/angular-resource.js"></script>
  <script src="../test/lib/angular/angular-mocks.js"></script>
  <script src="js/app.js"></script>
  <script src="js/controllers.js"></script>
  <script src="../test/e2e/myAppTest.js"></script>
</head>
<body>
  <div ng-view></div>
</body>
</html>

Then in your scenarios.js just reference your new test-index.html before running the other tests.

beforeEach(function() {
   browser().navigateTo('../../app/test-index.html#/');
});

I've adapted this example from:

https://github.com/stephennancekivell/angular_e2e_http/tree/ngMockE2E

EdL
  • 154
  • 1
  • 2
  • 8
  • 1
    how exactly are you going to test routes in your original app? The routes are configured with app name – wakandan Sep 19 '13 at 02:50
0

As a start, add angular-mocks.js and the file (app.js for example) where you will create the module to your index.html page that contains the ng-app declaration.

<html lang="en" ng-app="myApp">
  <head>
    <script src="js/app.js"></script>
    <script src="../test/lib/angular/angular-mocks.js"></script>
    ...

Then in the app.js file define the module and add the mock responses.

var myAppDev = angular.module('myApp', ['ngResource','ngMockE2E']);

myAppDev.run(function($httpBackend) {
    var user = {name: 'Sandra'};
    $httpBackend.whenGET('/api/user').respond(user); 
});
Sarah Vessels
  • 30,930
  • 33
  • 155
  • 222
Chris
  • 4,237
  • 6
  • 30
  • 42