Why do we need deployments.fixture? - blockchain

I have the following code below
const { deployments, ethers, getNamedAccounts } = require("hardhat")
describe("FundMe", async () => {
beforeEach(async () => {
const { deployer } = await getNamedAccounts()
await deployments.fixture(["all"])
fundMe = await ethers.getContract("FundMe")
console.log(fundMe, "fundMe")
})
it("test", () => {})
describe("constructor", async () => {})
})
I am running the mocks contract and the fundme contract before getting the fundme contract. However, I was wondering why we needed this? If these are my only two contracts it would work without deployments.fixture because it seems that hardhat runs all the contracts by default if no fixtures are specified?
I tried looking at the hardhat documentation.

fixture is used in testing to create a proper test environment. for example, if you write a smart contract which uses or interacts with some ERC20 tokens, in order to deploy the contract, you have to deploy those contracts. Or maybe some contracts inherits from interface and you need to provide those interfaces. that is what fixture is used to provide all necessary data in order to use your smart contract

Related

Is it safe to expose AWS Amplify like this?

In my react native app I use Amplify Datastore to query,create and update items. I want to know is it safe to expose these methods in my frontend ? and can someone reverse engineer and use these ? and what can I do to increase the security of these methods ?
const getOrder = async () => {
await DataStore.query(Order, c=>c.iD.eq(currentOrderId)
}
const createOrder = async () => {
await Datastore.save(new Order({
// }))
}
etc

How to mock Fastify plugin

I am trying to write unit testing for fastify application which also has custom fastify plugin.
Is there a way we can mock fastify plugin? I tried mocking using Jest and Sinon without much success.
Giorgios link to the file is broken, the mocks folder is now absent from the master branch. I dug the commit history to something around the time of his answer and I found a commit with the folder still there. I leave it here for those who will come in the future!
This is what works for me
Setup your plugin according to Fastify docs https://www.fastify.io/docs/latest/Reference/Plugins/
// establishDbConnection.ts
import fp from 'fastify-plugin';
import {FastifyInstance, FastifyPluginAsync} from 'fastify';
import { initDbConnection } from './myDbImpl';
const establishDbConnection: FastifyPluginAsync = async (fastify: FastifyInstance, opts) => {
fastify.addHook('onReady', async () => {
await initDbConnection()
});
};
export default fp(establishDbConnection);
mock the plugin with jest, make sure you wrap the mock function in fp() so that Fastify recognizes it as a plugin.
// myTest.ts
import fp from 'fastify-plugin';
const mockPlugin = fp(async () => jest.fn());
jest.mock('../../../fastifyPlugin/establishDbConnection', (() => {
return mockPlugin;
}));
Your question is a bit generic but if you are using Jest it must be enough for mocking a fastify plugin. You can take a look in this repo and more specifically this file . This is a mock file of fastify and you add the registered plugins and in the specific example addCustomHealthCheck and then in your test files you can just call jest.mock('fastify').
You do not give a specific use case and there are lot of reasons you might want to mock a plugin. The nature of the plugin to be mocked is important to giving a good answer. Because I don't know that specific information I will show how to mock a plugin that creates a decorator that stores data that can be retrieved with fastify.decorator-name. This is a common use case for plugins that connect to databases or store other widely needed variables.
In the below case, the goal is to test a query function that queries a db; a plugin stores the connection information via a fastify decorator. So, in order to unit test the query we specifically need to mock the client data for the connection.
First create an instance of fastify. Next, set up a mock to return the desired fake response. Then, instead of registering the component with fastify (which you could also do), simply decorate the required variables directly with mock information.
Here is the function to be tested. We need to mock a plugin for a database which creates a fastify decorator called db. Specifically, in the below case the function to be tested uses db.client:
const fastify = require("fastify")({ //this is here to gather logs
logger: {
level: "debug",
file: "./logs/combined.log"
}
});
const HOURS_FROM_LOADDATE = "12";
const allDataQuery = `
SELECT *
FROM todo_items
WHERE a."LOAD_DATE" > current_date - interval $1 hour
`;
const queryAll = async (db) => {
return await sendQuery(db, allDataQuery, [HOURS_FROM_LOADDATE]);
};
//send query to db and receive data
const sendQuery = async (db, query, queryParams) => {
var res = {};
try {
const todo_items = await db.client.any(query, queryParams);
res = todo_items;
} catch (e) {
fastify.log.error(e);
}
return res;
};
module.exports = {
queryByAsv
};
Following is the test case. We will mock db.client from the db plugin:
const { queryAll } = require("../src/query");
const any = {
any: jest.fn(() => {
return "mock response";
})
};
describe("should return db query", () => {
beforeAll(async () => {
// set up fastify for test instance
fastify_test = require("fastify")({
logger: {
level: "debug",
file: "./logs/combined.log",
prettyPrint: true
}
});
});
test("test Query All", async () => {
// mock client
const clientPromise = {
client: any
};
//
fastify_test.decorate("db", clientPromise);
const qAll = await queryAll(fastify_test.db);
expect(qAll).toEqual("mock response");
});
});

Mocking a Flow.js interface with Jest?

How might a Flow.js interface be mocked with Jest? To my surprise, I haven't found this issue addressed anywhere.
I'm fairly new to both, but the only (untested) option I see is to create a class that inherits from the interface and then mock the implementing class. This seems quite cumbersome and I don't believe I could place the implementing classes (which are what would actually be mocked) inside the __mocks__ folders expected by Jest and still get the expected behavior.
Any suggestions? Is there a more appropriate mocking tool?
Update
Why do I want to create a mock for an interface? This code intends to have a clean separation of the domain and implementation layers, with the domain classes using Flow interfaces for all injected dependencies. I want to test these domain classes. Using a mocking tool could ideally allow me to more easily and expressively modify the behavior of the mocked services and confirm that the domain class being tested is making the appropriate calls to these mocked services.
Here's a simplified example of a class that I would be testing in this scenario. UpdateResources would be the class under test, while ResourceServer and ResourceRepository are interfaces for services that I would like to mock and 'spy' upon:
// #flow
import type { ResourceServer } from '../ResourceServer';
import type { ResourceRepository } from '../ResourceRepository';
/**
* Use case for updating resources
*/
export default class UpdateResources {
resourceServer: ResourceServer;
resourceRepository: ResourceRepository;
constructor(resourceServer: ResourceServer, resourceRepository: ResourceRepository) {
this.resourceServer = resourceServer;
this.resourceRepository = resourceRepository;
}
async execute(): Promise<boolean> {
const updatesAvailable = await this.resourceServer.checkForUpdates();
if (updatesAvailable) {
const resources = await this.resourceServer.getResources();
await this.resourceRepository.saveAll(resources);
}
return updatesAvailable;
}
}
A solution
The approach I've arrived at which seems to work quite well for my purposes is to create a mock implementation of the interface in the __mocks__ directory what exposes jest.fn objects for all implemented methods. I then instantiate these mock implementations with new and skip any use of jest.mock().
__mocks__/MockResourceServer.js
import type { ResourceServer } from '../ResourceServer';
export default class MockResourceServer implements ResourceServer {
getResources = jest.fn(() => Promise.resolve({}));
checkForUpodates = jest.fn(() => Promise.resolve(true));
}
__mocks__/MockResourceRepository.js
import type { ResourceRepository } from '../ResourceRepository';
export default class MockResourceRepository implements ResourceRepository {
saveAll = jest.fn(() => Promise.resolve());
}
__tests__/UpdateResources.test.js
import UpdateResources from '../UpdateResources';
import MockResourceRepository from '../../__mocks__/MockResourceRepository';
import MockResourceServer from '../../__mocks__/MockResourceServer';
describe('UpdateResources', () => {
describe('execute()', () => {
const mockResourceServer = new MockResourceServer();
const mockResourceRepository = new MockResourceRepository();
beforeEach(() => {
jest.clearAllMocks();
});
it('should check the ResourceServer for updates', async () => {
const updateResources = new UpdateResources(mockResourceServer, mockResourceRepository);
await updateResources.execute();
expect(mockResourceServer.checkForUpdates).toHaveBeenCalledTimes(1);
});
it('should save to ResourceRepository if updates are available', async () => {
mockResourceServer.load.mockResolvedValue(true);
const updateResources = new UpdateResources(mockResourceServer, mockResourceRepository);
await updateResources.execute();
expect(mockResourceRepository.saveAll).toHaveBeenCalledTimes(1);
});
it('should NOT save to ResourceRepository if NO updates are available', async () => {
mockResourceServer.load.mockResolvedValue(false);
const updateResources = new UpdateResources(mockResourceServer, mockResourceRepository);
await updateResources.execute();
expect(mockResourceRepository.saveAll).not.toHaveBeenCalled();
});
});
});
If anyone can offer any improvements, I'm open!
The thing is, you don't actually need to mock an implementation of an interface. The purpose of a mock is to 'look like' the real thing, but if you already have an interface that says what the real thing should look like, any implementation that conforms to the interface will automatically serve equally well as a mock. In fact, from the point of view of the typechecker, there won't be a different between the 'real' and the 'mock' implementation.
Personally what I like to do is to create a mock implementation that can be constructed by feeding it mock responses. Then it can be reused in any test case by constructing it directly in that test case with the exact responses it should provide. I.e., you 'script' the mock with what it should say by injecting the responses at the time of construction. The difference between it and your mocking implementation is that if it doesn't have a response, it throws a exception and fails the test. Here's an article I wrote that shows this method: https://dev.to/yawaramin/interfaces-for-scaling-and-testing-javascript-1daj
With this technique, a test case might look like this:
it('should save to ResourceRepository if updates are available', async () => {
const updateResources = new UpdateResources(
new MockResourceServer({
checkForUpdates: [true],
getResources: [{}],
}),
new MockResourceRepository({
saveAll: [undefined],
}),
);
const result = await updateResources.execute();
expect(result).toBeTruthy();
});
What I like about these mocks is that all the responses are explicit, and show you the sequence of calls that are happening.

Angular 2 Testing a service which injects Http without using Testbed

I want to test a simple Angular 2 data service. The service uses Http, but nothing else. In the quickstart guide it says:
However, it's often more productive to explore the inner logic of
application classes with isolated unit tests that don't depend upon
Angular. Such tests are often smaller and easier to read, write, and
maintain.
The example of writing an isolated unit test it gives is that for simple services you can just test the service by creating a new instance of it in each test... maybe something like:
beforeEach(() => { service = new EventDataService(); });
it('#getEvents should return an observable', () => {
expect(service.getEvents()).toBe(Observable.from([]);
});
However, my EventDataService uses Http, so I get an error if I don't put Http in the constructor like so:
beforeEach(() => { service = new EventDataService(http: Http); });
But Http doesn't exist unless I import it, which I don't want to do - I don't want to test Http. I tried stubbing http out, but all the ways I tried ended up failing or leading me to import even MORE things to satisfy the Typescript gods...
I'm sure I'm over thinking this. I have tried the suggestions on quite a few sites that talk about testing in Angular 2, but anything older than a few months is suspect to me since the framework has changed so much in the last 6-12 months. I feel like I should be able to keep this simple for such a simple example.
Am I doing something obvious wrong?
I am using Angular 2 V 2.4.10, Webpack 2.3.1, Sinon 2.1.0, and Typescript 2.2.1.
Service:
import { Injectable } from "#angular/core";
import { Http } from "#angular/http";
import { Observable } from "rxjs";
import { Event } from "../event/event.interface";
#Injectable()
export class EventDataService {
events: Event[];
constructor(private http: Http) { }
getEvents(): Observable<Event[]> {
return this.http.get("api/events")
.map((response) => {return response.json(); })
}
};
Spec:
import { Http } from "#angular/http";
import { EventDataService } from "./event-data.service";
import * as sinon from "sinon";
import { expect } from "chai";
describe("Event Data Service", () => {
it("GetEvents", () => {
sinon.stub(Http, "get").returns(Promise.resolve("sinon Event!"));
let eventDataService = new EventDataService();
expect(eventDataService.getEvents()).to.equal("sinon event!");;
});
});
Thank you!
Although i wholeheartedly agree with the general sentiment that you should use TestBed in this scenario to stub out your Http dependency (after all, that's a huge motivator for why Angular has dependency injection in the first place), I'm seeing some errors in your approach which seems to indicate some misunderstanding.
Your EventDataService has a constructor which expects a single parameter of type Http. Therefore, whenever you want to create an instance of your EventDataService manually, you have to use the constructor and pass a single parameter of type Http.
So, you should be doing:
let dataService = new EventDataService(x);
where x is a variable of type Http. What may not be obvious is that Typescript is not a language like Java - Typescript can get out of your way if you want it to. So, you could, for eg, just create a new object, and say it's of type 'Http' and the Typescript compiler will assume you know what you're doing and let you proceed.
So you could do:
let x = ({ } as Http);
let dataService = new EventDataService(x);
The first line is telling the compiler that i want the type of {} to be Http, and Typescript will get out of your way and assume you know what you're doing.
So, you can use that technique to get an 'instance' of Http for your testing - i use the word 'instance' very loosely.
However, if you look at your EventDataService, it expects that the http object that gets passed to its constructor to have a get method that returns an object that you can call map on. In other words, it expects get to return an Observable. So, if you want to fake out Http for testing purposes, your fake Http instance needs to have a get method, and that get method needs to return an Observable.
Putting all of the above together, if i wanted to write my own test without using TestBed, I'd end up with:
let fakeHttp = {
get: (_: any) => {}
};
// I'm not familiar with sinon,
// but i believe this is stubbing the get method of fakeHttp
// and returning a canned response
sinon.stub(fakeHttp, "get").returns(Observable.of("sinon Event!"));
let eventDataService = new EventDataService(fakeHttp);
// remember, getEvents returns an observable,
// so to test it you have to subscribe to it and check its values
eventDataService.getEvents().subscribe(data => {
expect(data).to.equal("sinon Event!");
});
Would i approach this this way? Probably not - I'd just use TestBed to get a fake Http instance (not because this approach is that difficult, but just because TestBed simplifies things when you have multiple dependencies, and services always seem to grow that way). But at the end of the day, constructor dependency injection, like what Angular uses, is pretty easy to understand - pass your dependencies (fake or real) as parameters to the constructor of the class you're trying to create an instance of.
You should need to create a testing module and mock the response to test the service methods provide dependencies in your testing module
import { async, getTestBed, TestBed, inject } from "#angular/core/testing";
import { Response, ResponseOptions, HttpModule, XHRBackend } from "#angular/http";
import { MockBackend, MockConnection } from "#angular/http/testing";
import { EventDataService } from "./event-data.service";
describe("EventDataService", () => {
let mockBackend: MockBackend;
let service: EventDataService;
let injector: Injector;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
providers: [
{ provide: XHRBackend, useClass: MockBackend },
EventDataService
]
});
injector = getTestBed();
});
beforeEach(() => {
mockBackend = injector.get(XHRBackend);
service = injector.get(EventDataService);
});

How to unit test API calls with mocked fetch() in react-native with Jest

In React Native I use fetch to perform network requests, however fetch is not an explicitly required module, so it is seemingly impossible to mock in Jest.
Even trying to call a method which uses fetch in a test will result in:
ReferenceError: fetch is not defined
Is there a way to test such API requests in react native with Jest?
Inside your test case you can mock any function you want by using Jest's mocks:
fetch = jest.fn(() => Promise.resolve());
This approach works only for the promise-based test cases (see pit in the Jest docs).
As far as fetch is an async function, you need to run all your tests using pit (read more about async tests here).
Another approach where you mock the global fetch object:
const mockSuccesfulResponse = (
status = 200,
method = RequestType.GET,
returnBody?: object
) => {
global.fetch = jest.fn().mockImplementationOnce(() => {
return new Promise((resolve, reject) => {
resolve({
ok: true,
status,
json: () => {
return returnBody ? returnBody : {};
},
});
});
});
};
The above helper method can be modified any way you want :-) Hope it helps someone
Rather than rolling your own mock, you can use the jest-fetch-mock npm package to override the global fetch object. That package allows you to set up fake responses and verify sent requests. See that link for extensive usage examples.
I solved this by adding isomorphic-fetch.
$ npm install --save isomorphic-fetch
and using it like
import fetch from 'isomorphic-fetch';
...
fetch('http://foo.com');
whatwg-fetch might work as well
Suppose you want to test resolve and reject cases, for this first you mock the fetch behaviour and then use Jest's rejects and resolves methods with with assertion block
function fetchTodos() {
return fetch(`${window.location.origin}/todos.json`)
.then(response => response.json())
.catch(error => console.log(error))
}
describe('fetchTodos', () => {
it('returns promise resolving to parsed response', () => {
global.fetch = jest.fn(() => Promise.resolve({ json: () => ''}))
expect(fetchTodos()).resolves.toBe('');
})
it('returns promise handling the error', async () => {
global.fetch = jest.fn(() => Promise.reject(''))
expect(fetchTodos()).rejects.toBe('')
})
})
As #ArthurDenture recommended, you can use fetch-mock, but there are some additional packages you will need to install to make it work with React Native and Jest:
$ npm install --save-dev fetch-mock
$ npm install --save-dev babel-plugin-transform-runtime
$ npm install --save-dev babel-preset-env
You can then mock fetch requests in your tests. Here is an example:
// __tests__/App.test.js
import React from 'react';
import App from '../App';
import fetchMock from 'fetch-mock';
import renderer from 'react-test-renderer';
it('renders without crashing', () => {
fetchMock.mock('*', 'Hello World!');
const rendered = renderer.create(<App />).toJSON();
expect(rendered).toBeTruthy();
});
Due to problems using fetch-mock with jest, I've release fetch-mock-jest. It basically gives the full fetch-mock api, but with a few jest-specific helpers, and works out of the box with jest, without needing to do any tricky wiring yourself
As shown in the react-testing-library documentation, you can use the jest.spyOn() function, which will mock the fetch function only for the next time it is called.
const fakeUserResponse = {token: 'fake_user_token'}
jest.spyOn(window, 'fetch').mockImplementationOnce(() => {
return Promise.resolve({
json: () => Promise.resolve(fakeUserResponse),
})
})
react-testing-library