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

Handle primitive values #4

Open
jgornick opened this issue Dec 11, 2019 · 5 comments
Open

Handle primitive values #4

jgornick opened this issue Dec 11, 2019 · 5 comments

Comments

@jgornick
Copy link

I see some benefit to being able for mock<...>() to also mock primitive values.

For example:

interface Baz {
  quux: boolean
}

interface Foo {
  bar: string
  baz: Baz
}

const foo = mock<Foo>()

// modifidy mock return value for quux
foo.baz.quux.mockReturnValueOnce(false)

Refer to #3 and https://github.com/reergymerej/super-mockable-non-functions/blob/master/src/index.js

Thoughts?

@marchaos
Copy link
Owner

I'll take a look at this, but suspect that it will not work as you have specified there given how jest works and how I've implemented deep mocks.

It may require something like :

  mock<Foo>({
    baz: {
        quux: primitiveMock().mockReturnValueOnce(false)
   }
)

or

const foo = mock<Foo>()

// modifidy mock return value for quux
primitiveMock(foo.baz.quux).mockReturnValueOnce(false)

@perfectmak
Copy link

Is there any update on this? It would really be useful to the current project I'm testing.

@marchaos
Copy link
Owner

unfortunately since Jest does not support this, the only way to add this is to do as above. PRs welcome

@mhjam
Copy link

mhjam commented Feb 18, 2020

My current workaround is this:

	it('should mock a primitive', () => {
		const quuxGetter = jest.fn();
		const foo = mock<Foo>(); // mockDeep does not work!
		Object.defineProperty(foo.baz, 'quux', {
			get: quuxGetter
		});
		quuxGetter.mockReturnValue(false);

		expect(foo.baz.quux).toBe(false);
		expect(quuxGetter).toHaveBeenCalledTimes(1);
	});

If you do not need spying capabilities and just want quux to have a fixed value, you can do

	it('should mock a primitive', () => {
		const foo = mock<Foo>(); // mockDeep does not work!
		Object.defineProperty(foo.baz, 'quux', {
			get: () => false
		});

		expect(foo.baz.quux).toBe(false);
	});

But this seems to be more complicated then necessary. It should be possible to write

	it('should mock a primitive', () => {
		const foo = mock<Foo>();
		foo.baz.quux = false;

		expect(foo.baz.quux).toBe(false);
	});

And actually, this does work (even with mockDeep), but not for falsy values like in the example. I believe this is due to line 86 in Mock.ts, which reads
if (!obj[property]) {
but should rather be
if (!(property in obj)) {

@maddin1502
Copy link

maddin1502 commented May 19, 2020

this is due to line 86 in Mock.ts, which reads
if (!obj[property]) {
but should rather be
if (!(property in obj)) {

I tested this solution and it works great. Why is this fix not committed yet?

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

No branches or pull requests

5 participants