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

Allow to return null for mocks / fuzz testing #870

Closed
amannn opened this issue Jun 27, 2018 · 10 comments
Closed

Allow to return null for mocks / fuzz testing #870

amannn opened this issue Jun 27, 2018 · 10 comments
Labels
feature New addition or enhancement to existing solutions

Comments

@amannn
Copy link

amannn commented Jun 27, 2018

I've noticed in my apps that null pointer exceptions seem to be the major cause of runtime errors. Ideally these would be prevented by a type system, however I currently don't use one and it would be too much effort to add types to the code bases at this point.

However, the amount of components that connect to API data aren't that many. I'm using the mock capabilities of graphql-tools to generate mock API data that I can feed into those components to test if they generally work. Currently graphql-tools always returns an actual value if a field is nullable.

I was thinking if there was an option to allow nullable properties to return null, I could generate a bunch of sample data and see if my components are able to render with all of them. If the set is large enough, I think I could catch most issues where null checks are missing.

Would you be open to introducing such a flag to graphql-tools to allow nullable properties to actually be null? Something I'm not sure yet, is how this would work if you have explicitly defined mock resolvers for a given field. For my use case I'd like to also possibly skip them, without having to put a condition into all of them.

So something like this would be great:

addMockFunctionsToSchema({
  schema: mockSchema,
  mocks: enhancedMocks,
  randomizeNullableFields: true
});

Or:

addMockFunctionsToSchema({
  schema: mockSchema,
  mocks: enhancedMocks,
  resolveFieldToNull: (some, args, to, identify, the, field) =>
    Math.random() < 0.5
});

The latter example might be helpful for other use cases, as the user can decide per field if it should be null.

What do you think?

@ghost ghost added the feature New addition or enhancement to existing solutions label Jun 27, 2018
@amannn amannn changed the title Fuzz testing Allow to return null for mocks / fuzz testing Jun 27, 2018
@ghost ghost added the feature New addition or enhancement to existing solutions label Jun 27, 2018
@JakeDawkins
Copy link
Contributor

Hey! You're right. There's no way to do this easily right now. One thing you could do would be to use the customizable mocks ability to null out the appropriate fields randomly: https://www.apollographql.com/docs/graphql-tools/mocking.html#Customizing-mocks.

I think we could extend the mocking abilities to include something like this though in the future. Maybe allowNullFieldMocks would be a more descriptive name?

@amannn
Copy link
Author

amannn commented Jul 15, 2018

Hey @JakeDawkins, thanks for your reply.

Yes, you could implement it by customizing mocks, however you'd have to implement this for every single mock resolver. That's why I'd prefer a flag, which can also potentially return null for a field where a custom mock resolver is defined.

I like your suggestion for calling it allowNullFieldMocks. Would you consider adding this? Or would you like to see a PR? Thanks!

@amannn
Copy link
Author

amannn commented Aug 31, 2018

An even better implementation would be to not randomize null values, but generate a full response with all nullable types filled (as it is currently the case). And then creating the minimum, but complete set of variations of responses where nullable types are set to null. This way the test would also be deterministic and not depending on randomness 🙂

@mschipperheyn
Copy link

mschipperheyn commented May 30, 2019

There is a related more serious issue: #930 without an obvious workaround. If you have a preservedResolver (so, not mocked) mixed with mocked resolvers (preserveResolvers: true), null fields on the non mocked resolvers will also receive mock data.

@mschipperheyn
Copy link

If you use partial mocking this will create havoc on your login functionality. I just managed to create a workaround:
Let's say you have a Viewer type that contains your logged in user

type Viewer {
    user: User
}
Query: {
   viewer: (source, params, context) => ({
      user: context.user, // can be undefined
   }),
}

If you use mocking with preserveResolvers: true and no mocks are loaded for this type, user will still get a mocked value. Not good.

The workaround I implemented was explicitly returning null

Query: {
   viewer: (source, params, context) => ({
      user: context.user || null, 
   }),
}

If you don't return null and leave the user undefined, you will still get a mock value. So, perhaps this issue is more related to a value being undefined than it being null

@amannn
Copy link
Author

amannn commented May 31, 2019

Yep, I think that's a bit a different story. As you mentioned || null returns explicitly null there, that's probably also the solution for the linked issue. When a field is undefined, that's when graphql-tools knows that it should mock the field. I'm not sure if there's a better solution than this.

@willhowlett
Copy link

This would be a great feature so am adding a very late +1

@agileurbanite
Copy link

👍 +1

@ardatan
Copy link
Owner

ardatan commented Apr 14, 2021

Mocking has been almost rewritten from scratch.
See https://www.graphql-tools.com/docs/mocking/
Closing this issue for now, if this is still relevant please create a new issue. Thanks!

@ardatan ardatan closed this as completed Apr 14, 2021
@jmtimko5
Copy link

jmtimko5 commented Oct 28, 2022

I am still seeing this issue: #4792 would really appreciate any guidance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New addition or enhancement to existing solutions
Projects
None yet
Development

No branches or pull requests

7 participants