2

I'm trying to unit test a method in Angularjs controllers using jasminejs and Karma runner my method takes an image path in the argument and transforms that image to text (TESSERACT-OCR).

when i try to call a unit test like this it does not work :

TypeError: Attempted to assign to readonly property. at workFn

it('has to return text from image', inject(function($httpBackend) {
 $scope.ocr("./image.png");
 $httpBackend.expectPOST('/ocr').respond();
 expect( scope.oceriser.bind("./ocr.png")).toMatch("ocr");

}));

when i do the following:

it('has to return text from image', inject(function($httpBackend) {
 $scope.ocr("./image.png");
 $httpBackend.expectPOST('/ocr').respond();
 expect($scope.ocr("./ocr.png")).toMatch("ocr");

}));

i get this error :

Expected undefined to match 'éàîè'.

can i access the $scope.textes.text value from the test ??

My question is how can i access the $scope.textes.text value that contains ocerised text from my test file ? is it possible i don't think because it is inside an anonymous function.. Is this a correct unit test ? can i have more coverage in this unit test ?can anyone help me i'm new in testing with jasmine

1 Answer 1

1

Normally when unit testing an HTTP call, you set up the expectation against $httpBackend, call the function you are testing normally, then call $httpBackend.flush() to fake the expected HTTP response and complete the call synchronously, then test the outcome.

So, taking a stab at your test, it'd probably look more like this....

it('has to return text from image', inject(function($httpBackend) {

 var expected = {}; // the value expected from the HTTP request

 // set up the http expectation. this tells angular what you expect to have called through $http when flush() is called
 $httpBackend.expectPOST('/oceriser').respond(expected);

 // call the function you are testing
 scope.oceriser('./image.png');

 // flushes the pending fake HTTP response causing the call to oceriser above to complete synchronously, and the function will continue normally
 $httpBackend.flush();

 // now, verify that oceriser() did what you expect when the http call succeeds. you'll need to figure this out, but in this example, i assume textes contains no elements initially, but after oceriser is called, it will contain one element with the text property equal to expected
 expect(scope.textes.length).toBe(1);
 expect(scope.textes[0].text).toBe(expected);
 expect(scope.textes[0].source).toBe('./image.png')
}));
Sign up to request clarification or add additional context in comments.

3 Comments

when i change my array $scope.textes.push to an object like $scope.textes = {source : source , text : text } and when trying to access the property text inside the unit test file like expect(scope.textes.text).toBe(expected); i have a problem because the scope.textes.text property has the same value as expected variable. any ideas ?? do i need to use the scope.$digest() after flush() to synchronise the scope ??
No, $digest isn't necessary, as that will all be taken care of for you during an http request. This may be an issue of equality. toBe expects the value to be exactly the same, or in the instance of objects, for the objects to be the same instance. If you clone/copy and it looks the same but is a different instance, the test will fail. If you expect the same exact instance and it's failing, just step through your code and see where you went wrong.
if you want to test to make sure all of the data in the test is the same, you can add your own jasmine matcher (add in your describe before your tests). beforeEach(function(){ this.addMatchers({ toEqualData: function(expected) { return angular.equals(this.actual, expected); } }); });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.