2016-06-17 5 views
1

이 작업을 성공적으로 수행하기 위해 인터넷에서 찾은 모든 것을 시도했습니다. 내 서비스에서 기능을 테스트하려고했지만 내 서비스 범위에 따라 액세스하지 않습니다. 어떤 도움을 크게 감상 할 수있다 :)서비스 테스트 방법 - AngularJS/Jasmine

서비스 :

'use strict'; 

angular.module('Service').service('configService', function(
    $rootScope, $http) { 
    var configObj = null; 
    return { 

    getConfig: function() { 
     if (configObj != null) { 
     console.log("returning cached config"); 
     return configObj; 
     } 
     else { 
     return $http.get('conf.json').then(function(res) { 
      $http.get(res.confLocation).then(function(
      locationResponse) { 
      configObj = locationResponse; 
      $rootScope.configObj = configObj; 
      console.log($rootScope.configObj); 
      return configObj; 
      }); 
     }); 
     } 
    } 
    }; 
}); 

getConfig 내가 시도한 시험에서 액세스되고 있지 않습니다를.

ServiceTests는 :

'use strict'; 
describe('Service: configService', function() { 

    // load the controller's module 
    beforeEach(module('Service')); 

    var configService, $httpBackend, results, tstLocation, tstRes; 
    var tstConfig = { 
    "confLocation": "local-dev-conf.json" 
    }; 

    var tstConfigEmpty = {}; 
    var tstConfigObjEmpty = {}; 

    var tstConfigObj = { 
    "AWS": { 
     "region": "us-east-1", 
     "endpoint": "http://localhost:8133" 
    } 
    }; 

    // Initialize the controller and a mock scope 
    beforeEach(inject(function(_configService_, _$httpBackend_) { 
    inject(function($rootScope) { 
     $rootScope.USERNAME = 'TESTER'; 
     $rootScope.configObj = tstConfigObj; 
     $rootScope.locationResponse = tstLocation; 
     $rootScope.res = tstRes; 
    }); 

    configService = _configService_; 
    $httpBackend = _$httpBackend_; 

    //Problem here?? 
    spyOn(configService, 'getConfig').and.callFake(function() { 
     return { 
     then: function() { 
      return "something"; 
     } 
     }; 
    }); 

    })); 
    it('should return a promise', function() { 
    expect(configService.getConfig().then).toBeDefined(); 
    }); 

    it('should test backend stuff', inject(function() { 

    results = configService.getConfig(tstConfig); 
    $httpBackend.expectGET('conf.json').respond(tstConfig); 
    $httpBackend.expectGET('local-dev-conf.json').respond(tstConfigObj); 
    $httpBackend.flush(); 
    })); 

    //Thanks Miles 
    it('should check if it was called', inject(function() { 
    results = configService.getConfig().then(); 
    expect(configService.getConfig).toHaveBeenCalled(); 

    }); 
    // console.log(results); 
    })); 

    it('should check for a null configObj', inject(function() { 
    results = configService.getConfig(tstConfigObjEmpty).then(function() { 
     expect(results).toBe(null); 
    }); 
    // console.log(results); 
    // console.log(tstConfigObj); 
    })); 

    it('should check for a non-null configObj', inject(function() { 
    results = configService.getConfig(tstConfigObj).then(function() { 

     // Any string is accepted right now -- Why?? 
     expect(results).toEqual("returning cached config"); 
     expect(results).toBe("returning cached config"); 
     expect(results).toBe("your mom"); // SHOULDN'T BE WORKING BUT DOES 
     expect(results).toEqual("Object{AWS: Object{region: 'us-east-1', endpoint: 'http://localhost:8133'}}"); 
     expect(results).toBe("Object{AWS: Object{region: 'us-east-1', endpoint: 'http://localhost:8133'}}"); 
    }); 
    // console.log(results); 
    // console.log(tstConfigObj); 
    })); 

    it('should check for null file', inject(function() { 
    results = configService.getConfig(tstConfigEmpty).then(function() { 
     expect(results).toEqual(null); 
     expect(results).toBe(null); 
    }); 
    })); 

    it('should test a valid file', inject(function() { 
    results = configService.getConfig(tstConfig).then(function() { 
     expect(results).not.toBe(null); 
     expect(results).toEqual("Object{confLocation: 'local-dev-conf.json'}"); 
    }) 
}); 

나는 내가 잘못 spyOn를 사용하거나 제대로 내 테스트에서 getConfig에 접근하고 있지 않다 생각합니다. 생각?

편집 : Here is my code coverage

편집 2 : 변경 테스트 마일하지만 테스트 범위에 여전히 업데이트로 발견되는 문제에 대한 3 개 감사합니다. Amy가 지적한 것처럼 내 스파이 로직에 문제가 있습니다. 나는 callFake를 사용해서는 안된다.

EDIT 3 : 지금 마일 덕분에 기능에 액세스했습니다.

spyOn(configService, 'getConfig').and.callThrough(); 

후 추가 테스트 케이스 :는 내 spyOn을 변경했다

results = configService.getConfig(tstConfig).then(); 
expect(configService.getConfig).toHaveBeenCalled(); 

Coverage now (still needs work)

+0

and.callFake 대신 and.allerValue를 시도한 후 해당 값을 반환 했습니까? –

+0

I는 and.returnValue and.callFake으로 교체 시도뿐만 아니라 : "spyOn (configService 'getConfig') and.returnValue (함수() { 창 { 다음 :. 함수() { 복귀" 내가 할 때 내 9 개의 테스트 중 6 개가 충돌 함 – FF5Ninja

+0

다음 라인에서 함수가 호출되었는지 확인할 필요가 없습니다 _ _ 호출했습니다. –

답변

0

당신은 여기에 문제가 있습니다

results = configService.getConfig(tstConfigObj).then(function() { 
    expect(results).toHaveBeenCalled(); 
    expect(results).toHaveBeenCalledWith(tstConfigObj); 
}); 

getConfig이 매개 변수를 사용하지 않는, 그리고 어느 쪽도 아니 then하지 않습니다. 이 오류를 생략하면 results에는 then에서 "something"문자열이 할당됩니다. expect 문이 실행 되더라도 문자열이 호출되면 테스트중인 것 같습니다. 대신 다음을 시도하십시오 :

results = configService.getConfig().then(); 
expect(configService.getConfig).toHaveBeenCalled(); 
+0

응답 해 주셔서 고맙습니다. 나는 변화를 구현했지만 테스트가 통과되었지만 여전히 * getConfig *를 제공하지 않는다. ... Amy가 위에서 언급 한 것처럼 내 spyOn에 문제가 있다고 생각하지만 그걸 고치는 방법을 거의 모르겠습니다. – FF5Ninja

+0

'결과 = configService.getConfig (tstConfig) .then();'및 마지막으로'expect (configService.getConfig) .toHaveBeenCalled()를 사용하여'spyOn (configService, 'getConfig') and.callThrough); ' –

+0

그랬어! 마침내이 기능에 액세스했으며 42 %의 적용 범위에 있습니다. 코드의 나머지 부분을 작업 할 시간. – FF5Ninja

0

당신이 사용하는 재스민의 버전은 무엇? and.callFake 구문은 Jasmine 2.0에 추가되었습니다. 아마 테스트 스위트는 새로운 버전을 가리킬 필요가있을 것이다.

Jasmine 2.0 Docs

+0

Jasmine 2를 사용하고 있습니다.4.1 – FF5Ninja

1

Jasmine 1.3 Docs는 대신 함수의 가짜를 호출하고 있습니다. 따라서 함수 내부의 로직이 호출되지 않습니다.

+0

조금 더 자세히 설명해 주시겠습니까? 나는 Angular/Jasmine을 처음 보았고 아직 스파이를 이해하지 못했습니다. 감사! – FF5Ninja

+0

함수가 호출 된 것을 테스트 할 필요가 없다면 함수를 간첩하지 마십시오. 따라서이 서비스의 함수를 사용하는 테스트에서이를 스파이 할 수 있습니다. 당신이 스파이를해야한다면, 실행할 코드가 필요하다. @Miles P가 그의 코멘트에서 말했듯이'and.callThrough'를 사용하라. –