using angularjs controller that consumes a service promise inside the view

I have an controller that consumes an angularjs service promise. I have written jasmine unit tests against the controller and therefore the controller function looks like:

this.getTodos = function () {
    TodoService.getTodos().then(function (todos) {
        $scope.Todos = todos;
      },
        function (error) {
            // TODO: display the error pop up
            console.log(error);
        });
};

It seems like this does not work with the view? If I change the function to be as:

 TodoService.getTodos().then(function (todos) {
        $scope.Todos = todos;
      },
        function (error) {
            // TODO: display the error pop up
            console.log(error);
        });

then it works but then I cannot test my controller function. My preferred way would be to use it as this.getTodos, this.saveTodo, this.DeleteTodo etc ....

any suggestions please?

many thanks

====>> Update

As mentioned the tests are all working but the view does not show data; seems like controller this.getTodos is not called at all. .... I am not sure how to force angular view to use controller getTodos... Tests are below:

The following jasmine tests work fine:

    it("Reading todos...", inject(function ($q) {

        var deferredRead = $q.defer();
        spyOn(todoServiceMock, "getTodos").and.returnValue(deferredRead.promise);
        deferredRead.resolve([{ TodoId: 10, Description: "Test", Completed: false },
        { TodoId: 11, Description: "Test", Completed: false }]);
        todoController.getTodos();
        scope.$apply();

        expect(scope.Todos.length).toBe(2);
    }));

    it("Reading todos, error...", inject(function ($q) {

        var deferredRead = $q.defer();
        spyOn(todoServiceMock, "getTodos").and.returnValue(deferredRead.promise);
        deferredRead.reject("There are no todos available!");
        todoController.getTodos();
        scope.$apply();

        expect(scope.Todos.length).toBe([]);
    }));

However, the view does not populate the rows ...

The view has code like:

<tr class="animate" ng-repeat="Todo in Todos | orderBy:'TodoId' | filter: filterTodo">
                    <td class="col-sm-1">{{Todo.TodoId}}</td>
                    <td class="col-sm-3">{{Todo.Description}}</td>
                    <td class="col-sm-1">
                        <span class="glyphicon glyphicon-check" ng-show="   {{Todo.Completed}}==true"></span>
                        <span class="glyphicon glyphicon-unchecked" ng-show="{{Todo.Completed}}==false"></span>
                    </td>
                    <td class="col-sm-2">
                        <a href="" ng-click="selectTodo(Todo)"><span class="glyphicon glyphicon-edit"></span></a>
                    </td>
                </tr>


ANSWERS:


Angular won't call a function from your scope if you don't tell it to call it. So, you basically have 3 choices:

  1. Do as you did in your second attempt
  2. Call the function in your controller when it's instantiated:

    this.getTodos = function () { ... }; // define the method
    this.getTodos(); // call it
    
  3. Use ng-init in the view to call the getTodos() function.

Note that using the first or second technique shouldn't prevent you from unit-testing the controller. The unique difference is that your test should expect that the service call is made when the controller is instantiated (i.e. when $controller('TodoController') is called) rather than expect it to happen after it has been instantiated, when the getTodos() function is called.



 MORE:


 ? How to pass content from service to another service where something happens to that content and it is then passed to a controller?
 ? How do I return the response from an asynchronous call?
 ? Use of Promise in method returning Observable cause error
 ? Use of Promise in method returning Observable cause error
 ? Use of Promise in method returning Observable cause error
 ? Angular2 Observable - how to wait for all function calls in a loop to end before proceeding?
 ? Can't call methods inside catch or then of a Promise call
 ? Angular2 synchronous promise
 ? Ionic 2/Angular 2 promise returning observable
 ? How to return value of promise using angular 2