1

私はテスト結果を得ることができません私は非常に基本的な実装を使用して、より深いテストを理解しています。ユニットテストは、約束を使用する角度コントローラとサービスですか?

私は私のコントローラからアクセスして約束を返す工場を持っています。私は呼び出しが成功したことをテストし、応答をrepos varに割り当てたいと思っています。コードを以下に示します。

'use strict'; 

angular.module('app') 
    .factory('searchServ', function ($timeout, $q, $http) { 
    return { 
     fetch: function(user) { 
     var deferred = $q.defer(); 

     $timeout(function(){ 
      $http({method: 'GET', url: 'https://api.github.com/users/' + user + '/repos'}).then(function(repos) { 
      deferred.resolve(repos.data); 
      }, function(reason){ 
      deferred.reject(reason.status); 
      console.log(reason); 
      }); 
     }, 30); 

     return deferred.promise; 
     } 
    }; 
    }) 
    .controller('MainCtrl', function ($scope, searchServ) { 
    $scope.results = function(user) { 
     $scope.message = ''; 
     searchServ.fetch(user).then(function (repos) { 
     if(repos.length){ 
      $scope.message = ''; 
      $scope.repos = repos; 
     } 
     else{ 
      $scope.message = 'not found' 
     } 
     }, function(){ 
     $scope.message = 'not found'; 
     }); 
    }; 
    }); 

//Test 

'use strict'; 

describe('MainCtrl', function() { 
    var scope, searchServ, controller, deferred, repos = [{name: 'test'}]; 
    // load the controller's module 
    beforeEach(module('app')); 

    beforeEach(inject(function($controller, $rootScope, $q) { 
    searchServ = { 
     fetch: function() { 
     deferred = $q.defer(); 
     return deferred.promise; 
     } 
    }; 
    spyOn(searchServ, 'fetch').andCallThrough(); 
    scope = $rootScope.$new(); 
    controller = $controller('MainCtrl', { 
     $scope: scope, 
     fetchGithub: fetchGithub 
    }); 


    })); 
    it('should test', function() { 
    expect(scope.test).toEqual('ha'); 
    }); 

    it('should bind to scope', function() { 
    scope.results(); 
    scope.$digest(); 
    expect(scope.message).toEqual(''); 
    //expect(scope.repos).not.toBe(undefined); 
    }); 
}); 

がテストを実行すると、私は次のエラーを与える:

TypeError: undefined is not a function (evaluating 'spyOn(searchServ, 'fetch').andCallThrough()') in test/spec/controllers/main.js (line 15)

私はそれが同様に結合範囲をテストすることは、このようにテストすることができますどのように任意のアイデアを非同期呼び出しとして?

+0

「andCallThrough」はありません。これは 'and.callThrough'です。あなたは[遅延反パターン](https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern)を広く使用しています。あなたの場合はひどく不利になるでしょう。あなたのケースでは、searchServ.fetchは未解決の約束を返します。 – estus

+0

私はand.callThroughを試しましたが、いつも未定義を返します。私はこのフィドルのような別のアプローチを試みていました。https://jsfiddle.net/upoc0ott/2/でも未定義ですいずれかの方法を使用してアウト? – SinSync

答えて

2

コードには多くの問題があります。

this Plunkrを作成しました。 index.jsは、コードとテストケースを含むファイルです。私は、コンベンションとベストプラクティスに従って、ほとんどの部分を編集しました。

私はあなたを与えたかったいくつかのポインタがあります。

  • $httpは約束を返すので、あなたの代わりに約束を解決し、あなたの方法から別の約束を作成するのではなく、それを使用する必要があります。なぜタイムアウトが使用されているのか分かりません。そこで、searchServの依存関係から$q$timeoutを削除しました。
  • テストケースで、使用した変数deferredを削除して同じことを行いました。
  • あなたのサービスや他の依存関係を模擬するために angular-mocks.jsを使用しての代わりに、テストケース内部のサービスを定義する必要があります
  • (あなたがやっている方法を。)
  • あなたはあなたのコードの異なる部分をテストするための別のdescribeブロックを作成する必要があります(Aこの場合はcontroller)。

は、この情報がお役に立てば幸い!

+0

それは素晴らしい答えでした!時間をとってくれてありがとう。私は$ timeoutと$ qを使いました。なぜならそれらは約束ベースの呼び出しであり、あなたがそれを使ってファクトリ/サービスを生成するなら、それはあなたにそのアプローチを与えるでしょうが、$ httpもまた約束を返します。 :) – SinSync

関連する問題