Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jest cannot read property setItem #124

Open
zagoa opened this issue Oct 10, 2018 · 15 comments
Open

Jest cannot read property setItem #124

zagoa opened this issue Oct 10, 2018 · 15 comments

Comments

@zagoa
Copy link

zagoa commented Oct 10, 2018

I have a little problem with Jest. When I try to test a function using SInfo jest crash and says :

  TypeError: Cannot read property 'setItem' of undefined

Do you have any hint ?

@SebiVPS
Copy link
Contributor

SebiVPS commented Oct 10, 2018

I had the same issue, i made a PR, which is already merged. Should be fixed in version 5.2.6. Could you check your version?

@zagoa
Copy link
Author

zagoa commented Oct 10, 2018

Ok I was on 5.2.4, I upgrade this dependency but that change nothing. Did I miss something ?

@NachoJusticia
Copy link

I'm still having this problem with the version "5.3.0"

@lcorniglione
Copy link

Same issue version 5.4.0, trying to make a mock.

TypeError: _reactNativeSensitiveInfo.default.deleteItem is not a function

@zakdances
Copy link

Similar issue with 5.4.1

TypeError: _reactNativeSensitiveInfo.default.getItem is not a function

@konjoinfinity
Copy link

konjoinfinity commented Jul 17, 2019

I am also having this issue when attempting:

const key = "buzzes"
    var value = JSON.stringify(this.state.buzzes)
    await SInfo.setItem(key, value, {});

TypeError: _reactNativeSensitiveInfo.default.getItem is not a function

@guitorioadar
Copy link

Well in my case

$ cd ios
$ pod install
$ cd ..

this works for me...

@stale
Copy link

stale bot commented Jun 10, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Jun 10, 2020
@stale
Copy link

stale bot commented Jul 10, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the 🚧 stale label Jul 10, 2020
@atabariscanalp
Copy link

atabariscanalp commented Oct 5, 2020

I have a little problem with Jest. When I try to test a function using SInfo jest crash and says :

  TypeError: Cannot read property 'setItem' of undefined

Do you have any hint ?

I'm still having this issue with 6.0.0-alpha.6

@stale stale bot removed the 🚧 stale label Oct 5, 2020
@stale
Copy link

stale bot commented Nov 4, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the 🚧 stale label Nov 4, 2020
@Rafatcb
Copy link

Rafatcb commented Nov 12, 2020

You can create a mock for it. I created a simple one that satisfies my needs without needing to mock every function. Got some inspiration in @react-native-async-storage/async-storage mock.

__mocks__/react-native-sensitive-info.js:

const asMock = {
  __INTERNAL_MOCK_STORAGE__: {},

  getItem: jest.fn(async (key, options) => {
    const storeName = _getStoreName(options);

    const result = asMock.__INTERNAL_MOCK_STORAGE__[storeName]
      ? asMock.__INTERNAL_MOCK_STORAGE__[storeName][key]
      : undefined;

    return result;
  }),

  setItem: jest.fn(async (key, value, options) => {
    const storeName = _getStoreName(options);

    if (asMock.__INTERNAL_MOCK_STORAGE__[storeName] === undefined) {
      asMock.__INTERNAL_MOCK_STORAGE__[storeName] = {};
    }

    asMock.__INTERNAL_MOCK_STORAGE__[storeName][key] = value;
    return null;
  }),
};

const _getStoreName = options =>
  options.sharedPreferencesName || options.keychainService || 'default';

module.exports = asMock;

And when I need to mock a specific result in a test:

it('should mock', () => {
  const sensitiveInfoMock = jest.spyOn(RNSInfo, 'getItem');
  sensitiveInfoMock.mockImplementation(async () => 'specific value');

  // ... test

  sensitiveInfoMock.mockRestore();
});

If someone can mock all functions using the "options" object, I bet a PR would be welcome.

PS: The code above won't distinguish iOS and Android for sharedPreferencesName and keychainService due to _getStoreName implementation being unware of the current platform.

@stale stale bot removed the 🚧 stale label Nov 12, 2020
@stale stale bot added the 🚧 stale label Dec 12, 2020
Repository owner deleted a comment from stale bot Dec 13, 2020
@stale stale bot removed the 🚧 stale label Dec 13, 2020
@ingvardm
Copy link

ingvardm commented Aug 20, 2021

Blind code so take it for what it is...

// __mocks__/react-native-sensitive-info.js

class RNSInfo {
	static stores = new Map()

	static getServiceName(o) {
		return o.sharedPreferencesName
			|| o.keychainService
			|| 'default'
	}

	static validateString(s){
		if (typeof s !== 'string') throw new Error('Invalid string:', s)
	}

	static getItem = jest.fn(async (k, o) => {
		RNSInfo.validateString(k)

		const serviceName = RNSInfo.getServiceName(o)
		const service = RNSInfo.stores.get(serviceName)

		if(service) return service.get(k) || null
	})

	static getAllItems = jest.fn(async (o) => {
		const serviceName = RNSInfo.getServiceName(o)
		const service = RNSInfo.stores.get(serviceName)
		const mappedValues = []

		if(service?.size){
			for(const [k, v] of service.entries()){
				mappedValues.push({key: k, value: v, service: serviceName})
			}
		}

		return mappedValues
	})

	static setItem = jest.fn(async (k, v, o) => {
		RNSInfo.validateString(k)
		RNSInfo.validateString(v)

		const serviceName = getServiceName(o)
		let service = RNSInfo.stores.get(serviceName)

		if (!service){
			RNSInfo.stores.set(serviceName, new Map())
			service = RNSInfo.stores.get(serviceName)
		}

		service.set(k, v)

		return null
	})

	static deleteItem = jest.fn(async (k, o) => {
		RNSInfo.validateString(k)

		const serviceName = RNSInfo.getServiceName(o)
		const service = RNSInfo.stores.get(serviceName)

		if (service) service.delete(k)

		return null
	})

	static hasEnrolledFingerprints = jest.fn(async () => true)

	static setInvalidatedByBiometricEnrollment = jest.fn()

	// "Touch ID" | "Face ID" | false
	static isSensorAvailable = jest.fn(async () => 'Face ID')
}

module.exports = RNSInfo

@gabimoncha
Copy link

For some reason writing the mocks as __mocks__/react-native-sensitive-info.js didn't work for me.

So I added it inside jest.setup.js file

jest.mock('react-native-sensitive-info', () => {
// your mock here
});

@daku
Copy link

daku commented Sep 6, 2023

Had to change the contents of __mocks__/@react-native-async-storage/async-storage.js to:

const asyncMock = require('@react-native-async-storage/async-storage/jest/async-storage-mock')
export default asyncMock

The import from the corresponding d.ts file is just the type, so AsyncStorage object is empty. Haven't looked into root causing this though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests