0
votes

I am new to AngularJS unit testing and this is a best practices question. If I have a data factory and a controller in separate files, and the controller calls the factory, do I need to write test specs for both the factory and the controller. Example

Controller method and test:

// controller method ------------------------------------------------------
$scope.getAsset = function (id) {
    if ($scope.id != '0') {
        assetFactory.getAsset($scope.id)
        .then(function (response) {
            $scope.asset = response.data;
            //$scope.selectedDepartmentName = $scope.asset.DepartmentName;
        })
        .catch(function (error) {
            alertService.add('danger', 'Unable to load asset data: ' + error.statusText + '(' + error.status + '). Please report this error to the application administrator');
        });
    }
};

// test ------------------------------------------------------
beforeEach(inject(function (assetFactory) {
    spyOn(assetFactory, 'getAsset').and.callThrough();
}));

it('method getAsset() was called', inject(function (assetFactory) {
    scope.getAsset();
    expect(assetFactory.getAsset).toHaveBeenCalled();
}));

Factory method and test:

// factory method ------------------------------------------------------
factory.getAsset = function (id) {
    url = baseAddress + "asset/get/" + id;
    return $http.get(url);
};

// test ------------------------------------------------------
 beforeEach(inject(function (assetFactory) {
    spyOn(assetFactory, 'getAsset').and.callThrough();
}));

it('method getAsset() was called', inject(function (assetFactory) {
    assetFactory.getAsset();
    expect(assetFactory.getAsset).toHaveBeenCalled();
}));

The controller test spec is already testing the factory call. I could see if I had a factory not being called by a controller and maybe that is the argument for testing both. In fact, in this application all the factories are called within one or more controllers.

On the other hand, maybe I test all my factories and just make sure the controller methods that call the factories are defined, not even try to spy on them in the controller.

Any advice is appreciated.

1

1 Answers

0
votes

The main purpose of Unit Testing is to separate out the different aspects and then test them individually.

If you are doing a callThrough on spyOn you are basically calling the factory method. But with this, you are not checking the inner logic of the factory. This necessarily mean that for the given input parameters, you are getting the expected return values. But what happens inside the factory method is not tested.

I would advice to create a fake factory method inside controller using callFake on spyOn to separate out the testing of individual modules. And then test the factory separately.

[UPDATE]

For example in your snippet:

  • For your factory test, you should test the $http call and if the value returned by that $http call is valid or not.
  • For your controller test you can:

    spyOn(assetFactory,'getAsset').and.callFake(function(){ //return some dummyValue or write some dummyCode here })