I have created small project to check coverage results and have unexpected results. It's definitely a configuration error on my part, but I just can't figure out what I have to tweak in order to fix the issue. For this issue I am presenting the simplest file I can to expose the problem. The problem happens across my entire project.
Any help is greatly appreciated. Thank you!
Dependencies
{
"dependencies": {
"@angular/animations": "^15.2.0",
"@angular/common": "^15.2.0",
"@angular/compiler": "^15.2.0",
"@angular/core": "^15.2.0",
"@angular/forms": "^15.2.0",
"@angular/platform-browser": "^15.2.0",
"@angular/platform-browser-dynamic": "^15.2.0",
"@angular/router": "^15.2.0",
"@ngrx/effects": "^15.3.0",
"@ngrx/entity": "^15.3.0",
"@ngrx/router-store": "^15.3.0",
"@ngrx/store": "^15.3.0",
"@ngrx/store-devtools": "^15.3.0",
"bootstrap": "^5.2.3",
"jasmine-marbles": "^0.9.1",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.12.0"
},
"devDependencies": {
"@angular-builders/jest": "^15.0.0",
"@angular-devkit/build-angular": "^15.2.2",
"@angular-eslint/builder": "^15.2.1",
"@angular-eslint/eslint-plugin": "^15.2.1",
"@angular/cli": "~15.2.2",
"@angular/compiler-cli": "^15.2.0",
"@types/jest": "^29.4.1",
"@typescript-eslint/eslint-plugin": "^5.54.1",
"@typescript-eslint/parser": "^5.54.1",
"eslint": "^8.35.0",
"eslint-config-prettier": "^8.7.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-unused-imports": "^2.0.0",
"husky": "^4.2.5",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.5.0",
"jest-jasmine2": "^29.5.0",
"jest-junit": "^15.0.0",
"jest-preset-angular": "^13.0.0",
"lint-staged": "^13.2.0",
"prettier": "^2.8.4",
"ts-node": "10.9.1",
"typescript": "~4.9.4"
}
}
Jest Config
export default {
displayName: 'coffee-project',
testEnvironment: 'jsdom',
extensionsToTreatAsEsm: ['.ts'],
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
isolatedModules: true,
},
},
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
resetMocks: true,
coverageProvider: 'v8',
}
Test file
import {getSelectedCoffee, selectCoffeeList} from './coffee.selectors';
const coffeeDataMock = [
{
"id": 9809,
"uid": "e2bb804d-2f9c-4d4c-ac04-23d516c30e69",
"blend_name": "Express Bean",
"origin": "Nariño, Colombia",
"variety": "S795",
"notes": "balanced, smooth, graham cracker, leafy greens, medicinal",
"intensifier": "delicate"
},
{
"id": 9779,
"uid": "545b2556-2249-4eee-bb93-16588ecfb446",
"blend_name": "Goodbye Cake",
"origin": "Estelí, Nicaragua",
"variety": "Gesha",
"notes": "wild, smooth, lemonade, tomato, cranberry",
"intensifier": "lingering"
},
];
export const CoffeeStateMock = {
coffeeList: coffeeDataMock,
selectedCoffee: coffeeDataMock[0],
currentPage: 0,
loader: false
};
describe('Coffee selectors', () => {
it('should select CoffeeList', () => {
const result = selectCoffeeList({
'coffeeState': CoffeeStateMock
});
expect(result).toEqual(CoffeeStateMock.coffeeList)
});
it('should select CoffeeList', () => {
const result = getSelectedCoffee({
'coffeeState': CoffeeStateMock
});
expect(result).toEqual(CoffeeStateMock.selectedCoffee)
});
})
File tested
import {createFeatureSelector, createSelector} from '@ngrx/store';
import {CoffeeState} from './coffee.state';
import {CoffeeItem} from '../definitions/interface/coffee-item.interface';
export const getCoffeeState = createFeatureSelector<CoffeeState>('coffeeState');
export const selectCoffeeList = createSelector(
getCoffeeState,
(state: CoffeeState): CoffeeItem[] => state.coffeeList
);
export const getSelectedCoffee = createSelector(
getCoffeeState,
(state: CoffeeState): CoffeeItem => state.selectedCoffee!
);
export const selectCurrentPage = createSelector(
getCoffeeState,
(state: CoffeeState): number => state.currentPage
);
export const getLoaderStatus = createSelector(
getCoffeeState,
(state: CoffeeState): boolean => state.loader
);
export const getSlicedCoffeeList = createSelector(
selectCoffeeList,
selectCurrentPage,
(coffeeList, currentPage) => {
const pageItemsLimit = 10;
const startIndex = currentPage * pageItemsLimit;
const endIndex = startIndex + pageItemsLimit;
return (coffeeList || [])?.slice(startIndex, endIndex);
}
);
Coverage results for file
100% Statements 36/36
83.33% Branches 5/6
100% Functions 0/0
100% Lines 36/36

Expected behaviour My code coverage should illustrate actual result
So the part in your test that is highlighted in yellow is the part that is untested. In this statement:
(coffeeList || [])you have no test code that triggers the 2nd half of that statement to return[]. This will happen whencoffeeListisnullorundefinedHere's an example:
To get your code coverage to 100% you need to write a test that triggers that part of the code.
Possibly something like this. This is just to give you an idea, it might not be 100% functional code here