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

feat: better blockchain api mocking #255

Merged
merged 11 commits into from
Apr 30, 2020
Merged

Conversation

rflechtner
Copy link
Contributor

@rflechtner rflechtner commented Apr 17, 2020

NO-TICKET

This is a suggestion for better mocking of the blockchain api connection. Instead of mocking the entire Blockchain module, we would be able to mock only api calls, thus allowing us to use the original functions on the module. We would also only mock getCached on the BlockchainApiConnection module to inject our mocked API and retain originals of the remaining functions.
I have fixed unit tests that were relying on the old mocks via minimal effort solutions, but the new mocking would allow refactoring to make tests a lot more elegant (and realistic). Not sure whether this should be part of this PR or whether that calls for a ticket - given that this one PR itself wasn't a modification we had planned.

How to test:

unit tests are already using the new mocking.

Checklist:

  • I have verified that the code works
  • I have verified that the code is easy to understand
    • If not, I have left a well-balanced amount of inline comments
  • I have left the code in a better state
  • I have documented the changes (where applicable)

@rflechtner rflechtner self-assigned this Apr 17, 2020
@rflechtner rflechtner added the 🚨 tests chore: tests label Apr 17, 2020
@wischli wischli self-requested a review April 17, 2020 12:18
Copy link
Contributor

@wischli wischli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I like this approach. I would improve the default mock functions of __mocked_api though and maybe add some explanation there for non-intuitive mocks. For instance, your DID mock inside Mocktest.spec.ts was lacking information and had a kind of "what is this sorcery"-feeling. Moreover, the order of your explanatory comment was incorrect.

I will leave some comments at specific lines and submit my proposal for changes. Feel free to discard them as you wish.

new Option(
Tuple,
new Tuple(
// (publicBoxKey, publicSigningKey, documentStore?)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Order is publicSigningKey, publicBoxKey, documentStore

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, thanks, good catch! I copied that from somewhere, I'll try to keep this in mind for later.

}

function __getMockSubmittableExtrinsic(): SubmittableExtrinsic {
const result: SubmittableResult = TxresultsQueue.shift() || defaultTxResult
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would replace TxresultsQueue with TxResultsQueue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

absolutely

expect(result).toMatchObject({ isFinalized: true })
})

it('tx succeeds then fails', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would also add a single test for failed transaction, just to keep it simple.

children: jest.fn((id: string) => new Vec(Text, [])),
},
did: {
dIDs: jest.fn(id => new Option(Tuple)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will submit a proposal for a default query here. There, one can add explanatory comments and reference to this in custom mocks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My approach was to return null result queries by default (what would be returned by a query for something that is not there), because it seems odd to return a specific result as a default value. Would prefer to stick to that approach, but you're right that documentation and example cases must be given. I could comment this out and leave it as an example return value, and also add similar examples to the other queries?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense and I like your proposal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for documentation on how to set return values, I could also add a comment at the top of the mock or file that illustrates this once.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good if it's not too obvious as in this case!

@rflechtner
Copy link
Contributor Author

@wischli Thank you for your thorough review! Just so that we're on the same page: I added the Mocktest.spec.ts just for illustrative purposes and to make it easier to play around with the mock. Probably should have stated this clearly. Would you you advocate keeping this file in the repo as you made suggestions on it? Or is that just a hint to how I should refactor the unit tests that broke with this mock?

@wischli
Copy link
Contributor

wischli commented Apr 22, 2020

Would you you advocate keeping this file in the repo as you made suggestions on it? Or is that just a hint to how I should refactor the unit tests that broke with this mock?

Do as you wish. My suggestions can be treated as refactor hints 😇

@rflechtner rflechtner requested a review from wischli April 22, 2020 15:23
@rflechtner
Copy link
Contributor Author

@wischli I added documentation, is this better understandable now?

@wischli
Copy link
Contributor

wischli commented Apr 23, 2020

@wischli I added documentation, is this better understandable now?

) */

// default return value decodes to [], represents: no children found
children: jest.fn((id: string) => new Vec(H256, [])),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
children: jest.fn((id: string) => new Vec(H256, [])),
children: jest.fn((id: string) => new Vec(H256)),

@rflechtner rflechtner marked this pull request as ready for review April 29, 2020 12:53
Copy link
Contributor

@wischli wischli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me except for the two unused inputs. Really like the exemplary comments 👏

Copy link
Contributor

@tjwelde tjwelde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rflechtner rflechtner merged commit 58a2176 into develop Apr 30, 2020
@rflechtner rflechtner deleted the rf-BlockchainApi-mocking branch April 30, 2020 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🚨 tests chore: tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants