2016-06-17 8 views
1

Habe alles versucht, was ich im Internet gefunden habe, um diese Arbeit ohne Erfolg zu machen. Ich versuche, eine Funktion in meinem Dienst zu testen, aber gemäß meiner Berichterstattung greife ich nie darauf zu. Jede Hilfe wäre sehr dankbar :)Wie man einen Dienst ausspioniert, um es zu testen - AngularJS/Jasmine

Service:

'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 wird nie in den Tests zugegriffen wird, habe ich versucht.

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'}"); 
    }) 
}); 

Ich glaube, ich bin mit spyOn falsch oder getConfig in meinen Tests nicht richtig zugreifen. Gedanken?

EDIT: Here is my code coverage

EDIT 2: Geänderte Test 3 dank ein Problem von Miles gefunden, noch kein Update auf, obwohl die Testabdeckung. Irgendwas stimmt nicht mit meiner Spion-Logik, wie Amy darauf hingewiesen hat. Ich sollte nicht CallFake verwenden, scheint es?

EDIT 3: Haben Sie jetzt Zugriff auf die Funktion dank Miles. Hatte meine spyOn zu ändern:

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

fügen Sie dann den Testfall:

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

Coverage now (still needs work)

+0

Haben Sie versucht und.ReturnValue anstelle von und.CallFake und nur die Renable zurückgeben? –

+0

habe ich versucht, mit and.callFake and.returnValue ersetzen, sowie: "spyOn (ConfigService, 'getConfig') and.returnValue (function() {return { dann:. Function() { return" etwas ";" stürzt 6 meiner 9 Tests ab, wenn ich das tue – FF5Ninja

+0

Beachten Sie, dass es keine Notwendigkeit gibt zu überprüfen, dass eine Funktion in der nächsten Zeile aufgerufen wurde _nach Sie es angerufen haben_! –

Antwort

0

Sie haben ein Problem hier:

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

getConfig keine Parameter übernimmt, und auch nicht then. Ohne diese Fehler wird results die Zeichenfolge "etwas" von then zugewiesen. Selbst wenn die expect-Anweisungen ausgelöst werden, scheinen Sie zu testen, ob eine Zeichenfolge aufgerufen wurde. Versuchen Sie dies stattdessen:

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

Danke für die Antwort Miles. Ich implementierte die Änderung, und obwohl der Test bestanden hat, liefert es immer noch keine Abdeckung der * getConfig * ... Ich denke, es gibt ein Problem mit meinem SpyOn, wie Amy oben erwähnt, aber ich bin ein wenig unsicher, wie das zu beheben ist. – FF5Ninja

+0

Haben Sie versucht, 'spyOn (configService, 'getConfig') .und.callThrough();' then 'results = configService.getConfig (tstConfig) .then();' und schließlich 'expect (configService.getConfig) .toHaveBeenCalled (); ' –

+0

Das hat es geschafft! Es hat endlich auf die Funktion zugegriffen, und ich bin bei 42% Abdeckung. Zeit, den Rest des Codes zu bearbeiten, vielen Dank! – FF5Ninja

0

Welche Version von Jasmin verwenden Sie? Die Syntax "and.callFake" wurde in Jasmine 2.0 hinzugefügt. Vielleicht muss die Testsuite nur auf die neue Version verweisen.

Jasmine 1.3 Docs

Jasmine 2.0 Docs

+0

Ich benutze Jasmine 2.4.1 – FF5Ninja

1

Sie fordern eine gefälschte anstelle der Funktion. Die Logik innerhalb der Funktion wird also nicht aufgerufen.

+0

Würdest du ein wenig ausarbeiten können? Ich bin ziemlich neu in Angular/Jasmine und verstehe SpyOn noch nicht ganz. Vielen Dank! – FF5Ninja

+0

Spionieren Sie eine Funktion nicht aus, es sei denn, Sie müssen testen, ob sie aufgerufen wurde (Sie könnten also eine Funktion in diesem Dienst in einem Test nach etwas ausspionieren, das sie verwendet). Wenn du es ausspionieren musst _und_ brauchst du den Code, um es auszuführen, benutze 'and.callThrough', wie @Miles P in seinem Kommentar sagt. –