Explore all Mock open source software, libraries, packages, source code, cloud functions and APIs.

Popular New Releases in Mock

Faker

faker

Release v13.3.5

nock

v13.2.4

mockery

1.3.5

faker

v2.20.0

Popular Libraries in Mock

faker.js

by Marak doticonjavascriptdoticon

star image 33346 doticonNOASSERTION

generate massive amounts of realistic fake data in Node.js and the browser

Faker

by fzaninotto doticonphpdoticon

star image 26055 doticonNOASSERTION

Faker is a PHP library that generates fake data for you

Mock

by nuysoft doticonjavascriptdoticon

star image 17076 doticonMIT

A simulation data generator

faker

by joke2k doticonpythondoticon

star image 14046 doticonMIT

Faker is a Python package that generates fake data for you.

nock

by nock doticonjavascriptdoticon

star image 11375 doticonMIT

HTTP server mocking and expectations library for Node.js

mockery

by mockery doticonphpdoticon

star image 10062 doticonNOASSERTION

Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL).

faker

by faker-ruby doticonrubydoticon

star image 9969 doticonMIT

A library for generating fake data such as names, addresses, and phone numbers.

msw

by mswjs doticontypescriptdoticon

star image 8934 doticonMIT

Seamless REST/GraphQL API mocking library for browser and Node.js.

mock

by golang doticongodoticon

star image 6130 doticonApache-2.0

GoMock is a mocking framework for the Go programming language.

Trending New libraries in Mock

testable-mock

by alibaba doticonjavadoticon

star image 1433 doticonMIT

换种思路写Mock,让单元测试更简单

sharingan

by didi doticongodoticon

star image 1043 doticonApache-2.0

Sharingan(写轮眼)是一个基于golang的流量录制回放工具,适合项目重构、回归测试等。

dokz

by remorses doticontypescriptdoticon

star image 411 doticon

Effortless documentation with Next.js and MDX

wiremock-rs

by LukeMathWalker doticonrustdoticon

star image 329 doticonNOASSERTION

HTTP mocking to test Rust applications.

datanymizer

by datanymizer doticonrustdoticon

star image 328 doticonMIT

Powerful database anonymizer with flexible rules. Written in Rust.

interceptors

by mswjs doticontypescriptdoticon

star image 223 doticonMIT

Low-level HTTP/HTTPS/XHR/fetch request interception library.

common-random

by yindz doticonjavadoticon

star image 218 doticonApache-2.0

简单易用的随机数据生成器。生成各种比较真实的假数据。一般用于开发和测试阶段的数据填充模拟。支持各类中国特色本地化的数据格式。An easy-to use random data generator. Generally used for data filling, simulation, demonstration and other scenarios in the development and test phase.

Mystikal

by D00MFist doticonpythondoticon

star image 173 doticonBSD-3-Clause

macOS Initial Access Payload Generator

mocktail

by Huseyinnurbaki doticonjavascriptdoticon

star image 162 doticonMIT

Free, 11MB, containerized, self-hosted mock server.

Top Authors in Mock

1

bahmutov

7 Libraries

star icon133

2

HugoDF

5 Libraries

star icon66

3

php-mock

5 Libraries

star icon487

4

mcustiel

4 Libraries

star icon169

5

SpectoLabs

4 Libraries

star icon1997

6

meituan

4 Libraries

star icon12

7

meeshkan

4 Libraries

star icon215

8

h2non

4 Libraries

star icon1764

9

eloquent

4 Libraries

star icon236

10

Typescript-TDD

3 Libraries

star icon565

1

7 Libraries

star icon133

2

5 Libraries

star icon66

3

5 Libraries

star icon487

4

4 Libraries

star icon169

5

4 Libraries

star icon1997

6

4 Libraries

star icon12

7

4 Libraries

star icon215

8

4 Libraries

star icon1764

9

4 Libraries

star icon236

10

3 Libraries

star icon565

Trending Kits in Mock

Java Mock Open Source libraries have become an indispensable tool for developers to ensure their code is error-free. However, with so many Java Mock Open Source libraries out there, it can be difficult to discern which Java Mock Open Source libraries are the best, or if there are any that suit your project. It is always a good programming practice to write unit tests for each class we develop as part of our project. This helps us in identifying the bugs and also increases the stability of our code. Most of the time, while writing unit test cases, we need to mock external dependencies (like database connections or API calls) that we don’t want to test at that moment. We can do this with Java Mock Libraries. In this kit, we will discuss the top 8 Java Mock Open Source libraries that you can use in your testing project. mockito - popular Mocking framework for unit tests written; wiremock - A tool for mocking HTTP services; powermock - Mock |Java framework.

In software development, mock objects simulate the behavior and functionality of real objects, often to simplify unit testing. It is an object that mimics the behavior of another object, typically to simplify the testing of a class. A mock object can also be used to simulate how a client will use an API that hasn't yet been built or isn't ready for use. The procedure is a critical element of extreme programming, which relies on frequent releases in short development cycles and emphasizes comprehensive unit testing to ensure application stability. These are the 9 best Ruby Mock libraries in 2022, pact-ruby - Enables consumer-driven contract testing; Mocha - a mocking and stubbing library for Ruby; RSpec's - 'test double' framework, with support for stubbing and mocking; stripe-ruby-mock - A mocking library for testing stripe ruby.

Unit testing allows the programmer to refactor code or upgrade system libraries at a later date, and make sure the module still works correctly (e.g., in regression testing). The procedure is a critical element of extreme programming, which relies on frequent releases in short development cycles and emphasizes comprehensive unit testing to ensure application stability. Mock objects can be used as a replacement for real objects in unit testing, they often also record how they were used so that you can make assertions about this after the test has finished. Let's see the 14 best PHP Mock libraries in 2022, mockery - simple yet flexible PHP mock object framework; prophecy - Highly opinionated mocking framework for PHP 5.3; phpunit-mock-objects Mock Object library for PHPUnit.

Mock objects make it possible to write automated tests for code that depends on external services or resources. The most common scenario is when a web application depends on some kind of database. Mocking the database allows you to write tests that check that code that uses the database is operating correctly without actually performing any database operations (which may well be slow or impossible). In this kit, we will discuss the top 8 Python Mock Open Source libraries that you can use in your testing project. moto - easily mock out tests based on AWS infrastructure; responses - A utility for mocking out the Python Requests library; vcrpy - Automatically mock your HTTP interactions.

A mock object of a given class or interface is designed to simulate the behavior of the real object. Used to test the behavior of other objects that are dependent on this mock object. A mock object returns dummy data corresponding to some dummy input passed to it. Mock objects can be used as a replacement for real objects in unit testing, they often also record how they were used so that you can make assertions about this after the test has finished. In this kit, we will discuss the top 8 JavaScript Mock Open Source libraries that you can use in your testing project. nock - HTTP server mocking and expectations library for Node.js; sinon - Test spies, stubs and mocks for JavaScript; easy-mock - persistent service that generates mock data quickly.

Mocking is a process used in unit testing when the unit being tested has external dependencies. The purpose of mocking is to isolate and focus on the code being tested and not on the behavior or state of external dependencies. A mocking framework is a library that provides the ability to replace some components in your system with mock objects and make assertions about how they have been used. Go comes with built-in support for mocking: if you embed an interface in your struct, you can override it at will in your tests. Some great Go mocking libraries are testify - common assertions and mocks that plays nicely; go-sqlmock - Sql mock driver for golang to test database interactions; mockery - A mock code autogenerator for Golang.

Mocking is the act of replacing a function with a fake copy and optionally, configuring it to return some predefined data. The primary use case for mocking is unit testing. Mocking frameworks allow you to replace a specific call to a class or method with a behavior you define. Thanks to this ability, you can easily test units of code in isolation without messing up their dependencies These are the 11 best C# Mock libraries in 2022, NSubstitute - A friendly substitute for .NET mocking libraries; FakeItEasy - The easy mocking library for .NET; WireMock.Net - flexible library; pact-net - .NET version of Pact; moq.spikes - The most popular and friendly mocking framework for .NET.

Mocking frameworks allow you to replace a specific call to a class or method with a behavior you define. A mock object returns dummy data corresponding to some dummy input passed to it. Mock objects can be used as a replacement for real objects in unit testing, they often also record how they were used so that you can make assertions about this after the test has finished. When writing tests, developers often need to mock external libraries (e.g., database, network connections and etc.) to control the response from an external service. In C++, there are some good tools for this purpose.. These are the 5 best C++ Mock libraries CppUTes - unit testing and mocking framework for C/C; FakeIt - C++ mocking made easy; trompeloeil - Header only C14 mocking framework.

Trending Discussions on Mock

Change behaviour of AutoFixture with AutoMoq to return false for methods

The unauthenticated git protocol on port 9418 is no longer supported

Making a JSX syntax for a MockComponent and have it typed with typescript

Can not instantiate proxy of class: System.Net.HttpWebRequest. Could not find a parameterless constructor

Apache Beam Cloud Dataflow Streaming Stuck Side Input

How to compare file paths from JsonConfigurationSources and Directory.GetFiles properly?

How to get preview in composable functions that depend on a view model?

v0.8 AggregatorV3Interface.sol , its available in @chainlink/contracts?

Not able to mock a function inside useEffect

pytest/unittest: mock.patch function from module?

QUESTION

Change behaviour of AutoFixture with AutoMoq to return false for methods

Asked 2022-Mar-31 at 09:22

Say that I have the following interface:

1public interface ITeam
2{
3    bool HasPlayer(IPlayer player);
4    void AddPlayer(IPlayer player);
5}
6

I currently have a test that looks something along the lines of (using AutoMoq):

1public interface ITeam
2{
3    bool HasPlayer(IPlayer player);
4    void AddPlayer(IPlayer player);
5}
6[Theory]
7[MyAutoData]
8public void ShouldRosterToTeamWhenPlayerIsNotRostered(Player player, Mock<ITeam> mockedTeam)
9{
10    player.RosterToTeam(mockedTeam.Object);
11
12    mockedTeam.Verify(team => team.AddPlayer(player), Times.Once);
13}
14

However, a precondition in my code is that HasPlayer must return false for the test to pass when RosterToTeam is called.

This can be solved by creating a ICustomization and directly composing the correct behaviour, for example:

1public interface ITeam
2{
3    bool HasPlayer(IPlayer player);
4    void AddPlayer(IPlayer player);
5}
6[Theory]
7[MyAutoData]
8public void ShouldRosterToTeamWhenPlayerIsNotRostered(Player player, Mock<ITeam> mockedTeam)
9{
10    player.RosterToTeam(mockedTeam.Object);
11
12    mockedTeam.Verify(team => team.AddPlayer(player), Times.Once);
13}
14public class TeamCustomization : ICustomization
15{
16    public void Customize(IFixture fixture)
17    {
18        fixture.Customize<Mock<ITeam>>(composer =>
19            composer.Do(mock =>
20                        mock.Setup(team => team.HasPlayer(It.IsAny<IPlayer>()))
21                            .Returns(false)));
22    }
23}
24

However, I'd like my tests always to assume that the boolean methods have a default value of false. I've tried looking into ISpecimenBuilder, but couldn't see a way to achieve this, as it seems to only work on properties, parameters, etc.

Is anyone able to recommend me a way of generically setting up all boolean methods to return false by default when created in this fashion?

Edit: The culprit behind the behaviour change is when ConfigureMembers = true is set for AutoMoqCustomization.

This is what my MyAutoDataAttribute currently looks like:

1public interface ITeam
2{
3    bool HasPlayer(IPlayer player);
4    void AddPlayer(IPlayer player);
5}
6[Theory]
7[MyAutoData]
8public void ShouldRosterToTeamWhenPlayerIsNotRostered(Player player, Mock<ITeam> mockedTeam)
9{
10    player.RosterToTeam(mockedTeam.Object);
11
12    mockedTeam.Verify(team => team.AddPlayer(player), Times.Once);
13}
14public class TeamCustomization : ICustomization
15{
16    public void Customize(IFixture fixture)
17    {
18        fixture.Customize<Mock<ITeam>>(composer =>
19            composer.Do(mock =>
20                        mock.Setup(team => team.HasPlayer(It.IsAny<IPlayer>()))
21                            .Returns(false)));
22    }
23}
24public class MyAutoDataAttribute : AutoDataAttribute
25{
26    public MyAutoDataAttribute() : base(Create)
27    {
28    }
29
30    private static IFixture Create()
31    {
32        var fixture = new Fixture();
33
34        fixture.Customize(new AutoMoqCustomization
35        {
36            ConfigureMembers = true
37        });
38
39        fixture.Customize(new TeamCustomization());
40
41        return fixture;
42    }
43}
44

For my use case, ConfigureMembers = true is still needed (and would like to remove the TeamCustomization).

ANSWER

Answered 2022-Mar-26 at 16:40

First of all, you may want to use AutoMoqDataAttribute to create a mock of the ITeam interface:

1public interface ITeam
2{
3    bool HasPlayer(IPlayer player);
4    void AddPlayer(IPlayer player);
5}
6[Theory]
7[MyAutoData]
8public void ShouldRosterToTeamWhenPlayerIsNotRostered(Player player, Mock<ITeam> mockedTeam)
9{
10    player.RosterToTeam(mockedTeam.Object);
11
12    mockedTeam.Verify(team => team.AddPlayer(player), Times.Once);
13}
14public class TeamCustomization : ICustomization
15{
16    public void Customize(IFixture fixture)
17    {
18        fixture.Customize<Mock<ITeam>>(composer =>
19            composer.Do(mock =>
20                        mock.Setup(team => team.HasPlayer(It.IsAny<IPlayer>()))
21                            .Returns(false)));
22    }
23}
24public class MyAutoDataAttribute : AutoDataAttribute
25{
26    public MyAutoDataAttribute() : base(Create)
27    {
28    }
29
30    private static IFixture Create()
31    {
32        var fixture = new Fixture();
33
34        fixture.Customize(new AutoMoqCustomization
35        {
36            ConfigureMembers = true
37        });
38
39        fixture.Customize(new TeamCustomization());
40
41        return fixture;
42    }
43}
44public class AutoMoqDataAttribute : AutoDataAttribute
45{
46    public AutoMoqDataAttribute()
47        : base(new Fixture().Customize(new AutoMoqCustomization()))
48    {
49    }
50}
51

There is no need in cusomizing fixture to configure your mocks. You'd better do that in the tests itself (the arrange section):

1public interface ITeam
2{
3    bool HasPlayer(IPlayer player);
4    void AddPlayer(IPlayer player);
5}
6[Theory]
7[MyAutoData]
8public void ShouldRosterToTeamWhenPlayerIsNotRostered(Player player, Mock<ITeam> mockedTeam)
9{
10    player.RosterToTeam(mockedTeam.Object);
11
12    mockedTeam.Verify(team => team.AddPlayer(player), Times.Once);
13}
14public class TeamCustomization : ICustomization
15{
16    public void Customize(IFixture fixture)
17    {
18        fixture.Customize<Mock<ITeam>>(composer =>
19            composer.Do(mock =>
20                        mock.Setup(team => team.HasPlayer(It.IsAny<IPlayer>()))
21                            .Returns(false)));
22    }
23}
24public class MyAutoDataAttribute : AutoDataAttribute
25{
26    public MyAutoDataAttribute() : base(Create)
27    {
28    }
29
30    private static IFixture Create()
31    {
32        var fixture = new Fixture();
33
34        fixture.Customize(new AutoMoqCustomization
35        {
36            ConfigureMembers = true
37        });
38
39        fixture.Customize(new TeamCustomization());
40
41        return fixture;
42    }
43}
44public class AutoMoqDataAttribute : AutoDataAttribute
45{
46    public AutoMoqDataAttribute()
47        : base(new Fixture().Customize(new AutoMoqCustomization()))
48    {
49    }
50}
51[Theory, AutoMoqData]
52public void ShouldRosterToTeamWhenPlayerIsNotRostered(Player player, Mock<ITeam> mockedTeam)
53{
54    mockedTeam.Setup(t => t.HasPlayer(player)).Returns(false);
55    player.RosterToTeam(mockedTeam.Object);
56    mockedTeam.Verify(team => team.AddPlayer(player), Times.Once);
57}
58
59[Theory, AutoMoqData]
60public void ShouldNotRosterToTeamWhenPlayerIsRostered(Player player, Mock<ITeam> mockedTeam)
61{
62    mockedTeam.Setup(t => t.HasPlayer(player)).Returns(true);
63    player.RosterToTeam(mockedTeam.Object);
64    mockedTeam.Verify(team => team.AddPlayer(player), Times.Never);
65}
66

and, finaly, the simplified RoastToTeam implementation:

1public interface ITeam
2{
3    bool HasPlayer(IPlayer player);
4    void AddPlayer(IPlayer player);
5}
6[Theory]
7[MyAutoData]
8public void ShouldRosterToTeamWhenPlayerIsNotRostered(Player player, Mock<ITeam> mockedTeam)
9{
10    player.RosterToTeam(mockedTeam.Object);
11
12    mockedTeam.Verify(team => team.AddPlayer(player), Times.Once);
13}
14public class TeamCustomization : ICustomization
15{
16    public void Customize(IFixture fixture)
17    {
18        fixture.Customize<Mock<ITeam>>(composer =>
19            composer.Do(mock =>
20                        mock.Setup(team => team.HasPlayer(It.IsAny<IPlayer>()))
21                            .Returns(false)));
22    }
23}
24public class MyAutoDataAttribute : AutoDataAttribute
25{
26    public MyAutoDataAttribute() : base(Create)
27    {
28    }
29
30    private static IFixture Create()
31    {
32        var fixture = new Fixture();
33
34        fixture.Customize(new AutoMoqCustomization
35        {
36            ConfigureMembers = true
37        });
38
39        fixture.Customize(new TeamCustomization());
40
41        return fixture;
42    }
43}
44public class AutoMoqDataAttribute : AutoDataAttribute
45{
46    public AutoMoqDataAttribute()
47        : base(new Fixture().Customize(new AutoMoqCustomization()))
48    {
49    }
50}
51[Theory, AutoMoqData]
52public void ShouldRosterToTeamWhenPlayerIsNotRostered(Player player, Mock<ITeam> mockedTeam)
53{
54    mockedTeam.Setup(t => t.HasPlayer(player)).Returns(false);
55    player.RosterToTeam(mockedTeam.Object);
56    mockedTeam.Verify(team => team.AddPlayer(player), Times.Once);
57}
58
59[Theory, AutoMoqData]
60public void ShouldNotRosterToTeamWhenPlayerIsRostered(Player player, Mock<ITeam> mockedTeam)
61{
62    mockedTeam.Setup(t => t.HasPlayer(player)).Returns(true);
63    player.RosterToTeam(mockedTeam.Object);
64    mockedTeam.Verify(team => team.AddPlayer(player), Times.Never);
65}
66public class Player
67{
68    public void RosterToTeam(ITeam team)
69    {
70        if (team.HasPlayer(this))
71        {
72            return;
73        }
74        team.AddPlayer(this);
75    }
76}
77

Source https://stackoverflow.com/questions/71626344

QUESTION

The unauthenticated git protocol on port 9418 is no longer supported

Asked 2022-Mar-27 at 13:23

I have been using github actions for quite sometime but today my deployments started failing. Below is the error from github action logs

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7

Upon investigation, it appears that below section in my yml file is causing the issue.

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9

I have looked into this change log but can't seem to comprehend the issue.

Additional Details: Server: EC2 Instance Github actions steps:

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9  steps:
10  - name: Checkout
11    uses: actions/checkout@v2
12
13  - id: vars
14    run: |
15      if [ '${{ github.ref }}' == 'refs/heads/master' ]; then echo "::set-output name=environment::prod_stackstream" ; echo "::set-output name=api-url::api" ; elif [ '${{ github.ref }}' == 'refs/heads/staging' ]; then echo "::set-output name=environment::staging_stackstream"  ; echo "::set-output name=api-url::stagingapi" ; else echo "::set-output name=environment::dev_stackstream" ; echo "::set-output name=api-url::devapi" ; fi
16
17  - uses: pCYSl5EDgo/cat@master
18    id: slack
19    with:
20      path: .github/workflows/slack.txt
21
22  - name: Slack Start Notification
23    uses: 8398a7/action-slack@v3
24    env:
25      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
26      ENVIRONMENT: '`${{ steps.vars.outputs.environment }}`'
27      COLOR: good
28      STATUS: '`Started`'
29    with:
30      status: custom
31      fields: workflow,job,commit,repo,ref,author,took
32      custom_payload: |
33        ${{ steps.slack.outputs.text }}
34
35  - name: Installing modules
36    env:
37      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
38    run: yarn install
39
40  - name: Create Frontend Build
41    env:
42      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
43    run: yarn build
44
45  - name: Deploy to Frontend Server DEV
46    if: ${{ contains(github.ref, 'dev') }}
47    uses: easingthemes/ssh-deploy@v2.1.5
48    env:
49      SSH_PRIVATE_KEY: ${{ secrets.DEV_KEY }}
50      ARGS: '-rltgoDzvO --delete'
51      SOURCE: 'deploy/'
52      REMOTE_HOST: ${{ secrets.DEV_HOST }}
53      REMOTE_USER: plyfolio-dev
54      TARGET: '/home/plyfolio-dev/${{ steps.vars.outputs.environment }}/fe/deploy'
55

package.json file

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9  steps:
10  - name: Checkout
11    uses: actions/checkout@v2
12
13  - id: vars
14    run: |
15      if [ '${{ github.ref }}' == 'refs/heads/master' ]; then echo "::set-output name=environment::prod_stackstream" ; echo "::set-output name=api-url::api" ; elif [ '${{ github.ref }}' == 'refs/heads/staging' ]; then echo "::set-output name=environment::staging_stackstream"  ; echo "::set-output name=api-url::stagingapi" ; else echo "::set-output name=environment::dev_stackstream" ; echo "::set-output name=api-url::devapi" ; fi
16
17  - uses: pCYSl5EDgo/cat@master
18    id: slack
19    with:
20      path: .github/workflows/slack.txt
21
22  - name: Slack Start Notification
23    uses: 8398a7/action-slack@v3
24    env:
25      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
26      ENVIRONMENT: '`${{ steps.vars.outputs.environment }}`'
27      COLOR: good
28      STATUS: '`Started`'
29    with:
30      status: custom
31      fields: workflow,job,commit,repo,ref,author,took
32      custom_payload: |
33        ${{ steps.slack.outputs.text }}
34
35  - name: Installing modules
36    env:
37      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
38    run: yarn install
39
40  - name: Create Frontend Build
41    env:
42      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
43    run: yarn build
44
45  - name: Deploy to Frontend Server DEV
46    if: ${{ contains(github.ref, 'dev') }}
47    uses: easingthemes/ssh-deploy@v2.1.5
48    env:
49      SSH_PRIVATE_KEY: ${{ secrets.DEV_KEY }}
50      ARGS: '-rltgoDzvO --delete'
51      SOURCE: 'deploy/'
52      REMOTE_HOST: ${{ secrets.DEV_HOST }}
53      REMOTE_USER: plyfolio-dev
54      TARGET: '/home/plyfolio-dev/${{ steps.vars.outputs.environment }}/fe/deploy'
55   {
56  "name": "stackstream-fe",
57  "version": "1.0.0",
58  "authors": [
59    "fayyaznofal@gmail.com"
60  ],
61  "private": true,
62  "dependencies": {
63    "@fortawesome/fontawesome-svg-core": "^1.2.34",
64    "@fortawesome/free-solid-svg-icons": "^5.15.2",
65    "@fortawesome/react-fontawesome": "^0.1.14",
66    "@fullcalendar/bootstrap": "^5.5.0",
67    "@fullcalendar/core": "^5.5.0",
68    "@fullcalendar/daygrid": "^5.5.0",
69    "@fullcalendar/interaction": "^5.5.0",
70    "@fullcalendar/react": "^5.5.0",
71    "@lourenci/react-kanban": "^2.1.0",
72    "@redux-saga/simple-saga-monitor": "^1.1.2",
73    "@testing-library/jest-dom": "^5.11.9",
74    "@testing-library/react": "^11.2.3",
75    "@testing-library/user-event": "^12.6.0",
76    "@toast-ui/react-chart": "^1.0.2",
77    "@types/jest": "^26.0.14",
78    "@types/node": "^14.10.3",
79    "@types/react": "^16.9.49",
80    "@types/react-dom": "^16.9.8",
81    "@vtaits/react-color-picker": "^0.1.1",
82    "apexcharts": "^3.23.1",
83    "availity-reactstrap-validation": "^2.7.0",
84    "axios": "^0.21.1",
85    "axios-mock-adapter": "^1.19.0",
86    "axios-progress-bar": "^1.2.0",
87    "bootstrap": "^5.0.0-beta2",
88    "chart.js": "^2.9.4",
89    "chartist": "^0.11.4",
90    "classnames": "^2.2.6",
91    "components": "^0.1.0",
92    "dotenv": "^8.2.0",
93    "draft-js": "^0.11.7",
94    "echarts": "^4.9.0",
95    "echarts-for-react": "^2.0.16",
96    "firebase": "^8.2.3",
97    "google-maps-react": "^2.0.6",
98    "history": "^4.10.1",
99    "i": "^0.3.6",
100    "i18next": "^19.8.4",
101    "i18next-browser-languagedetector": "^6.0.1",
102    "jsonwebtoken": "^8.5.1",
103    "leaflet": "^1.7.1",
104    "lodash": "^4.17.21",
105    "lodash.clonedeep": "^4.5.0",
106    "lodash.get": "^4.4.2",
107    "metismenujs": "^1.2.1",
108    "mkdirp": "^1.0.4",
109    "moment": "2.29.1",
110    "moment-timezone": "^0.5.32",
111    "nouislider-react": "^3.3.9",
112    "npm": "^7.6.3",
113    "prop-types": "^15.7.2",
114    "query-string": "^6.14.0",
115    "react": "^16.13.1",
116    "react-apexcharts": "^1.3.7",
117    "react-auth-code-input": "^1.0.0",
118    "react-avatar": "^3.10.0",
119    "react-bootstrap": "^1.5.0",
120    "react-bootstrap-editable": "^0.8.2",
121    "react-bootstrap-sweetalert": "^5.2.0",
122    "react-bootstrap-table-next": "^4.0.3",
123    "react-bootstrap-table2-editor": "^1.4.0",
124    "react-bootstrap-table2-paginator": "^2.1.2",
125    "react-bootstrap-table2-toolkit": "^2.1.3",
126    "react-chartist": "^0.14.3",
127    "react-chartjs-2": "^2.11.1",
128    "react-color": "^2.19.3",
129    "react-confirm-alert": "^2.7.0",
130    "react-content-loader": "^6.0.1",
131    "react-countdown": "^2.3.1",
132    "react-countup": "^4.3.3",
133    "react-cropper": "^2.1.4",
134    "react-data-table-component": "^6.11.8",
135    "react-date-picker": "^8.0.6",
136    "react-datepicker": "^3.4.1",
137    "react-dom": "^16.13.1",
138    "react-draft-wysiwyg": "^1.14.5",
139    "react-drag-listview": "^0.1.8",
140    "react-drawer": "^1.3.4",
141    "react-dropzone": "^11.2.4",
142    "react-dual-listbox": "^2.0.0",
143    "react-facebook-login": "^4.1.1",
144    "react-flatpickr": "^3.10.6",
145    "react-google-login": "^5.2.2",
146    "react-hook-form": "^7.15.2",
147    "react-i18next": "^11.8.5",
148    "react-icons": "^4.2.0",
149    "react-image-lightbox": "^5.1.1",
150    "react-input-mask": "^2.0.4",
151    "react-jvectormap": "^0.0.16",
152    "react-leaflet": "^3.0.5",
153    "react-meta-tags": "^1.0.1",
154    "react-modal-video": "^1.2.6",
155    "react-notifications": "^1.7.2",
156    "react-number-format": "^4.7.3",
157    "react-perfect-scrollbar": "^1.5.8",
158    "react-rangeslider": "^2.2.0",
159    "react-rating": "^2.0.5",
160    "react-rating-tooltip": "^1.1.6",
161    "react-redux": "^7.2.1",
162    "react-responsive-carousel": "^3.2.11",
163    "react-router-dom": "^5.2.0",
164    "react-script": "^2.0.5",
165    "react-scripts": "3.4.3",
166    "react-select": "^4.3.1",
167    "react-sparklines": "^1.7.0",
168    "react-star-ratings": "^2.3.0",
169    "react-super-responsive-table": "^5.2.0",
170    "react-switch": "^6.0.0",
171    "react-table": "^7.6.3",
172    "react-toastify": "^7.0.3",
173    "react-toastr": "^3.0.0",
174    "react-twitter-auth": "0.0.13",
175    "reactstrap": "^8.8.1",
176    "recharts": "^2.0.8",
177    "redux": "^4.0.5",
178    "redux-saga": "^1.1.3",
179    "reselect": "^4.0.0",
180    "sass": "^1.37.5",
181    "simplebar-react": "^2.3.0",
182    "styled": "^1.0.0",
183    "styled-components": "^5.2.1",
184    "toastr": "^2.1.4",
185    "typescript": "^4.0.2",
186    "universal-cookie": "^4.0.4"
187  },
188  "devDependencies": {
189    "@typescript-eslint/eslint-plugin": "^2.27.0",
190    "@typescript-eslint/parser": "^2.27.0",
191    "@typescript-eslint/typescript-estree": "^4.15.2",
192    "eslint-config-prettier": "^6.10.1",
193    "eslint-plugin-prettier": "^3.1.2",
194    "husky": "^4.2.5",
195    "lint-staged": "^10.1.3",
196    "prettier": "^1.19.1",
197    "react-test-renderer": "^16.13.1",
198    "redux-devtools-extension": "^2.13.8",
199    "redux-mock-store": "^1.5.4"
200  },
201  "scripts": {
202    "start": "react-scripts start",
203    "build": "react-scripts build && mv build ./deploy/build",
204    "build-local": "react-scripts build",
205    "test": "react-scripts test",
206    "eject": "react-scripts eject"
207  },
208  "eslintConfig": {
209    "extends": "react-app"
210  },
211  "husky": {
212    "hooks": {
213      "pre-commit": "lint-staged"
214    }
215  },
216  "lint-staged": {
217    "*.{js,ts,tsx}": [
218      "eslint --fix"
219    ]
220  },
221  "browserslist": {
222    "production": [
223      ">0.2%",
224      "not dead",
225      "not op_mini all"
226    ],
227    "development": [
228      "last 1 chrome version",
229      "last 1 firefox version",
230      "last 1 safari version"
231    ]
232  }
233}
234

ANSWER

Answered 2022-Mar-16 at 07:01

First, this error message is indeed expected on Jan. 11th, 2022.
See "Improving Git protocol security on GitHub".

January 11, 2022 Final brownout.

This is the full brownout period where we’ll temporarily stop accepting the deprecated key and signature types, ciphers, and MACs, and the unencrypted Git protocol.
This will help clients discover any lingering use of older keys or old URLs.

Second, check your package.json dependencies for any git:// URL, as in this example, fixed in this PR.

As noted by Jörg W Mittag:

There was a 4-month warning.
The entire Internet has been moving away from unauthenticated, unencrypted protocols for a decade, it's not like this is a huge surprise.

Personally, I consider it less an "issue" and more "detecting unmaintained dependencies".

Plus, this is still only the brownout period, so the protocol will only be disabled for a short period of time, allowing developers to discover the problem.

The permanent shutdown is not until March 15th.


For GitHub Actions:

As in actions/checkout issue 14, you can add as a first step:

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9  steps:
10  - name: Checkout
11    uses: actions/checkout@v2
12
13  - id: vars
14    run: |
15      if [ '${{ github.ref }}' == 'refs/heads/master' ]; then echo "::set-output name=environment::prod_stackstream" ; echo "::set-output name=api-url::api" ; elif [ '${{ github.ref }}' == 'refs/heads/staging' ]; then echo "::set-output name=environment::staging_stackstream"  ; echo "::set-output name=api-url::stagingapi" ; else echo "::set-output name=environment::dev_stackstream" ; echo "::set-output name=api-url::devapi" ; fi
16
17  - uses: pCYSl5EDgo/cat@master
18    id: slack
19    with:
20      path: .github/workflows/slack.txt
21
22  - name: Slack Start Notification
23    uses: 8398a7/action-slack@v3
24    env:
25      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
26      ENVIRONMENT: '`${{ steps.vars.outputs.environment }}`'
27      COLOR: good
28      STATUS: '`Started`'
29    with:
30      status: custom
31      fields: workflow,job,commit,repo,ref,author,took
32      custom_payload: |
33        ${{ steps.slack.outputs.text }}
34
35  - name: Installing modules
36    env:
37      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
38    run: yarn install
39
40  - name: Create Frontend Build
41    env:
42      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
43    run: yarn build
44
45  - name: Deploy to Frontend Server DEV
46    if: ${{ contains(github.ref, 'dev') }}
47    uses: easingthemes/ssh-deploy@v2.1.5
48    env:
49      SSH_PRIVATE_KEY: ${{ secrets.DEV_KEY }}
50      ARGS: '-rltgoDzvO --delete'
51      SOURCE: 'deploy/'
52      REMOTE_HOST: ${{ secrets.DEV_HOST }}
53      REMOTE_USER: plyfolio-dev
54      TARGET: '/home/plyfolio-dev/${{ steps.vars.outputs.environment }}/fe/deploy'
55   {
56  "name": "stackstream-fe",
57  "version": "1.0.0",
58  "authors": [
59    "fayyaznofal@gmail.com"
60  ],
61  "private": true,
62  "dependencies": {
63    "@fortawesome/fontawesome-svg-core": "^1.2.34",
64    "@fortawesome/free-solid-svg-icons": "^5.15.2",
65    "@fortawesome/react-fontawesome": "^0.1.14",
66    "@fullcalendar/bootstrap": "^5.5.0",
67    "@fullcalendar/core": "^5.5.0",
68    "@fullcalendar/daygrid": "^5.5.0",
69    "@fullcalendar/interaction": "^5.5.0",
70    "@fullcalendar/react": "^5.5.0",
71    "@lourenci/react-kanban": "^2.1.0",
72    "@redux-saga/simple-saga-monitor": "^1.1.2",
73    "@testing-library/jest-dom": "^5.11.9",
74    "@testing-library/react": "^11.2.3",
75    "@testing-library/user-event": "^12.6.0",
76    "@toast-ui/react-chart": "^1.0.2",
77    "@types/jest": "^26.0.14",
78    "@types/node": "^14.10.3",
79    "@types/react": "^16.9.49",
80    "@types/react-dom": "^16.9.8",
81    "@vtaits/react-color-picker": "^0.1.1",
82    "apexcharts": "^3.23.1",
83    "availity-reactstrap-validation": "^2.7.0",
84    "axios": "^0.21.1",
85    "axios-mock-adapter": "^1.19.0",
86    "axios-progress-bar": "^1.2.0",
87    "bootstrap": "^5.0.0-beta2",
88    "chart.js": "^2.9.4",
89    "chartist": "^0.11.4",
90    "classnames": "^2.2.6",
91    "components": "^0.1.0",
92    "dotenv": "^8.2.0",
93    "draft-js": "^0.11.7",
94    "echarts": "^4.9.0",
95    "echarts-for-react": "^2.0.16",
96    "firebase": "^8.2.3",
97    "google-maps-react": "^2.0.6",
98    "history": "^4.10.1",
99    "i": "^0.3.6",
100    "i18next": "^19.8.4",
101    "i18next-browser-languagedetector": "^6.0.1",
102    "jsonwebtoken": "^8.5.1",
103    "leaflet": "^1.7.1",
104    "lodash": "^4.17.21",
105    "lodash.clonedeep": "^4.5.0",
106    "lodash.get": "^4.4.2",
107    "metismenujs": "^1.2.1",
108    "mkdirp": "^1.0.4",
109    "moment": "2.29.1",
110    "moment-timezone": "^0.5.32",
111    "nouislider-react": "^3.3.9",
112    "npm": "^7.6.3",
113    "prop-types": "^15.7.2",
114    "query-string": "^6.14.0",
115    "react": "^16.13.1",
116    "react-apexcharts": "^1.3.7",
117    "react-auth-code-input": "^1.0.0",
118    "react-avatar": "^3.10.0",
119    "react-bootstrap": "^1.5.0",
120    "react-bootstrap-editable": "^0.8.2",
121    "react-bootstrap-sweetalert": "^5.2.0",
122    "react-bootstrap-table-next": "^4.0.3",
123    "react-bootstrap-table2-editor": "^1.4.0",
124    "react-bootstrap-table2-paginator": "^2.1.2",
125    "react-bootstrap-table2-toolkit": "^2.1.3",
126    "react-chartist": "^0.14.3",
127    "react-chartjs-2": "^2.11.1",
128    "react-color": "^2.19.3",
129    "react-confirm-alert": "^2.7.0",
130    "react-content-loader": "^6.0.1",
131    "react-countdown": "^2.3.1",
132    "react-countup": "^4.3.3",
133    "react-cropper": "^2.1.4",
134    "react-data-table-component": "^6.11.8",
135    "react-date-picker": "^8.0.6",
136    "react-datepicker": "^3.4.1",
137    "react-dom": "^16.13.1",
138    "react-draft-wysiwyg": "^1.14.5",
139    "react-drag-listview": "^0.1.8",
140    "react-drawer": "^1.3.4",
141    "react-dropzone": "^11.2.4",
142    "react-dual-listbox": "^2.0.0",
143    "react-facebook-login": "^4.1.1",
144    "react-flatpickr": "^3.10.6",
145    "react-google-login": "^5.2.2",
146    "react-hook-form": "^7.15.2",
147    "react-i18next": "^11.8.5",
148    "react-icons": "^4.2.0",
149    "react-image-lightbox": "^5.1.1",
150    "react-input-mask": "^2.0.4",
151    "react-jvectormap": "^0.0.16",
152    "react-leaflet": "^3.0.5",
153    "react-meta-tags": "^1.0.1",
154    "react-modal-video": "^1.2.6",
155    "react-notifications": "^1.7.2",
156    "react-number-format": "^4.7.3",
157    "react-perfect-scrollbar": "^1.5.8",
158    "react-rangeslider": "^2.2.0",
159    "react-rating": "^2.0.5",
160    "react-rating-tooltip": "^1.1.6",
161    "react-redux": "^7.2.1",
162    "react-responsive-carousel": "^3.2.11",
163    "react-router-dom": "^5.2.0",
164    "react-script": "^2.0.5",
165    "react-scripts": "3.4.3",
166    "react-select": "^4.3.1",
167    "react-sparklines": "^1.7.0",
168    "react-star-ratings": "^2.3.0",
169    "react-super-responsive-table": "^5.2.0",
170    "react-switch": "^6.0.0",
171    "react-table": "^7.6.3",
172    "react-toastify": "^7.0.3",
173    "react-toastr": "^3.0.0",
174    "react-twitter-auth": "0.0.13",
175    "reactstrap": "^8.8.1",
176    "recharts": "^2.0.8",
177    "redux": "^4.0.5",
178    "redux-saga": "^1.1.3",
179    "reselect": "^4.0.0",
180    "sass": "^1.37.5",
181    "simplebar-react": "^2.3.0",
182    "styled": "^1.0.0",
183    "styled-components": "^5.2.1",
184    "toastr": "^2.1.4",
185    "typescript": "^4.0.2",
186    "universal-cookie": "^4.0.4"
187  },
188  "devDependencies": {
189    "@typescript-eslint/eslint-plugin": "^2.27.0",
190    "@typescript-eslint/parser": "^2.27.0",
191    "@typescript-eslint/typescript-estree": "^4.15.2",
192    "eslint-config-prettier": "^6.10.1",
193    "eslint-plugin-prettier": "^3.1.2",
194    "husky": "^4.2.5",
195    "lint-staged": "^10.1.3",
196    "prettier": "^1.19.1",
197    "react-test-renderer": "^16.13.1",
198    "redux-devtools-extension": "^2.13.8",
199    "redux-mock-store": "^1.5.4"
200  },
201  "scripts": {
202    "start": "react-scripts start",
203    "build": "react-scripts build && mv build ./deploy/build",
204    "build-local": "react-scripts build",
205    "test": "react-scripts test",
206    "eject": "react-scripts eject"
207  },
208  "eslintConfig": {
209    "extends": "react-app"
210  },
211  "husky": {
212    "hooks": {
213      "pre-commit": "lint-staged"
214    }
215  },
216  "lint-staged": {
217    "*.{js,ts,tsx}": [
218      "eslint --fix"
219    ]
220  },
221  "browserslist": {
222    "production": [
223      ">0.2%",
224      "not dead",
225      "not op_mini all"
226    ],
227    "development": [
228      "last 1 chrome version",
229      "last 1 firefox version",
230      "last 1 safari version"
231    ]
232  }
233}
234    - name: Fix up git URLs
235      run: echo -e '[url "https://github.com/"]\n  insteadOf = "git://github.com/"' >> ~/.gitconfig
236

That will change any git://github.com/ into https://github.com/.

For local projects

For all your repositories, you can set:

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9  steps:
10  - name: Checkout
11    uses: actions/checkout@v2
12
13  - id: vars
14    run: |
15      if [ '${{ github.ref }}' == 'refs/heads/master' ]; then echo "::set-output name=environment::prod_stackstream" ; echo "::set-output name=api-url::api" ; elif [ '${{ github.ref }}' == 'refs/heads/staging' ]; then echo "::set-output name=environment::staging_stackstream"  ; echo "::set-output name=api-url::stagingapi" ; else echo "::set-output name=environment::dev_stackstream" ; echo "::set-output name=api-url::devapi" ; fi
16
17  - uses: pCYSl5EDgo/cat@master
18    id: slack
19    with:
20      path: .github/workflows/slack.txt
21
22  - name: Slack Start Notification
23    uses: 8398a7/action-slack@v3
24    env:
25      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
26      ENVIRONMENT: '`${{ steps.vars.outputs.environment }}`'
27      COLOR: good
28      STATUS: '`Started`'
29    with:
30      status: custom
31      fields: workflow,job,commit,repo,ref,author,took
32      custom_payload: |
33        ${{ steps.slack.outputs.text }}
34
35  - name: Installing modules
36    env:
37      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
38    run: yarn install
39
40  - name: Create Frontend Build
41    env:
42      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
43    run: yarn build
44
45  - name: Deploy to Frontend Server DEV
46    if: ${{ contains(github.ref, 'dev') }}
47    uses: easingthemes/ssh-deploy@v2.1.5
48    env:
49      SSH_PRIVATE_KEY: ${{ secrets.DEV_KEY }}
50      ARGS: '-rltgoDzvO --delete'
51      SOURCE: 'deploy/'
52      REMOTE_HOST: ${{ secrets.DEV_HOST }}
53      REMOTE_USER: plyfolio-dev
54      TARGET: '/home/plyfolio-dev/${{ steps.vars.outputs.environment }}/fe/deploy'
55   {
56  "name": "stackstream-fe",
57  "version": "1.0.0",
58  "authors": [
59    "fayyaznofal@gmail.com"
60  ],
61  "private": true,
62  "dependencies": {
63    "@fortawesome/fontawesome-svg-core": "^1.2.34",
64    "@fortawesome/free-solid-svg-icons": "^5.15.2",
65    "@fortawesome/react-fontawesome": "^0.1.14",
66    "@fullcalendar/bootstrap": "^5.5.0",
67    "@fullcalendar/core": "^5.5.0",
68    "@fullcalendar/daygrid": "^5.5.0",
69    "@fullcalendar/interaction": "^5.5.0",
70    "@fullcalendar/react": "^5.5.0",
71    "@lourenci/react-kanban": "^2.1.0",
72    "@redux-saga/simple-saga-monitor": "^1.1.2",
73    "@testing-library/jest-dom": "^5.11.9",
74    "@testing-library/react": "^11.2.3",
75    "@testing-library/user-event": "^12.6.0",
76    "@toast-ui/react-chart": "^1.0.2",
77    "@types/jest": "^26.0.14",
78    "@types/node": "^14.10.3",
79    "@types/react": "^16.9.49",
80    "@types/react-dom": "^16.9.8",
81    "@vtaits/react-color-picker": "^0.1.1",
82    "apexcharts": "^3.23.1",
83    "availity-reactstrap-validation": "^2.7.0",
84    "axios": "^0.21.1",
85    "axios-mock-adapter": "^1.19.0",
86    "axios-progress-bar": "^1.2.0",
87    "bootstrap": "^5.0.0-beta2",
88    "chart.js": "^2.9.4",
89    "chartist": "^0.11.4",
90    "classnames": "^2.2.6",
91    "components": "^0.1.0",
92    "dotenv": "^8.2.0",
93    "draft-js": "^0.11.7",
94    "echarts": "^4.9.0",
95    "echarts-for-react": "^2.0.16",
96    "firebase": "^8.2.3",
97    "google-maps-react": "^2.0.6",
98    "history": "^4.10.1",
99    "i": "^0.3.6",
100    "i18next": "^19.8.4",
101    "i18next-browser-languagedetector": "^6.0.1",
102    "jsonwebtoken": "^8.5.1",
103    "leaflet": "^1.7.1",
104    "lodash": "^4.17.21",
105    "lodash.clonedeep": "^4.5.0",
106    "lodash.get": "^4.4.2",
107    "metismenujs": "^1.2.1",
108    "mkdirp": "^1.0.4",
109    "moment": "2.29.1",
110    "moment-timezone": "^0.5.32",
111    "nouislider-react": "^3.3.9",
112    "npm": "^7.6.3",
113    "prop-types": "^15.7.2",
114    "query-string": "^6.14.0",
115    "react": "^16.13.1",
116    "react-apexcharts": "^1.3.7",
117    "react-auth-code-input": "^1.0.0",
118    "react-avatar": "^3.10.0",
119    "react-bootstrap": "^1.5.0",
120    "react-bootstrap-editable": "^0.8.2",
121    "react-bootstrap-sweetalert": "^5.2.0",
122    "react-bootstrap-table-next": "^4.0.3",
123    "react-bootstrap-table2-editor": "^1.4.0",
124    "react-bootstrap-table2-paginator": "^2.1.2",
125    "react-bootstrap-table2-toolkit": "^2.1.3",
126    "react-chartist": "^0.14.3",
127    "react-chartjs-2": "^2.11.1",
128    "react-color": "^2.19.3",
129    "react-confirm-alert": "^2.7.0",
130    "react-content-loader": "^6.0.1",
131    "react-countdown": "^2.3.1",
132    "react-countup": "^4.3.3",
133    "react-cropper": "^2.1.4",
134    "react-data-table-component": "^6.11.8",
135    "react-date-picker": "^8.0.6",
136    "react-datepicker": "^3.4.1",
137    "react-dom": "^16.13.1",
138    "react-draft-wysiwyg": "^1.14.5",
139    "react-drag-listview": "^0.1.8",
140    "react-drawer": "^1.3.4",
141    "react-dropzone": "^11.2.4",
142    "react-dual-listbox": "^2.0.0",
143    "react-facebook-login": "^4.1.1",
144    "react-flatpickr": "^3.10.6",
145    "react-google-login": "^5.2.2",
146    "react-hook-form": "^7.15.2",
147    "react-i18next": "^11.8.5",
148    "react-icons": "^4.2.0",
149    "react-image-lightbox": "^5.1.1",
150    "react-input-mask": "^2.0.4",
151    "react-jvectormap": "^0.0.16",
152    "react-leaflet": "^3.0.5",
153    "react-meta-tags": "^1.0.1",
154    "react-modal-video": "^1.2.6",
155    "react-notifications": "^1.7.2",
156    "react-number-format": "^4.7.3",
157    "react-perfect-scrollbar": "^1.5.8",
158    "react-rangeslider": "^2.2.0",
159    "react-rating": "^2.0.5",
160    "react-rating-tooltip": "^1.1.6",
161    "react-redux": "^7.2.1",
162    "react-responsive-carousel": "^3.2.11",
163    "react-router-dom": "^5.2.0",
164    "react-script": "^2.0.5",
165    "react-scripts": "3.4.3",
166    "react-select": "^4.3.1",
167    "react-sparklines": "^1.7.0",
168    "react-star-ratings": "^2.3.0",
169    "react-super-responsive-table": "^5.2.0",
170    "react-switch": "^6.0.0",
171    "react-table": "^7.6.3",
172    "react-toastify": "^7.0.3",
173    "react-toastr": "^3.0.0",
174    "react-twitter-auth": "0.0.13",
175    "reactstrap": "^8.8.1",
176    "recharts": "^2.0.8",
177    "redux": "^4.0.5",
178    "redux-saga": "^1.1.3",
179    "reselect": "^4.0.0",
180    "sass": "^1.37.5",
181    "simplebar-react": "^2.3.0",
182    "styled": "^1.0.0",
183    "styled-components": "^5.2.1",
184    "toastr": "^2.1.4",
185    "typescript": "^4.0.2",
186    "universal-cookie": "^4.0.4"
187  },
188  "devDependencies": {
189    "@typescript-eslint/eslint-plugin": "^2.27.0",
190    "@typescript-eslint/parser": "^2.27.0",
191    "@typescript-eslint/typescript-estree": "^4.15.2",
192    "eslint-config-prettier": "^6.10.1",
193    "eslint-plugin-prettier": "^3.1.2",
194    "husky": "^4.2.5",
195    "lint-staged": "^10.1.3",
196    "prettier": "^1.19.1",
197    "react-test-renderer": "^16.13.1",
198    "redux-devtools-extension": "^2.13.8",
199    "redux-mock-store": "^1.5.4"
200  },
201  "scripts": {
202    "start": "react-scripts start",
203    "build": "react-scripts build && mv build ./deploy/build",
204    "build-local": "react-scripts build",
205    "test": "react-scripts test",
206    "eject": "react-scripts eject"
207  },
208  "eslintConfig": {
209    "extends": "react-app"
210  },
211  "husky": {
212    "hooks": {
213      "pre-commit": "lint-staged"
214    }
215  },
216  "lint-staged": {
217    "*.{js,ts,tsx}": [
218      "eslint --fix"
219    ]
220  },
221  "browserslist": {
222    "production": [
223      ">0.2%",
224      "not dead",
225      "not op_mini all"
226    ],
227    "development": [
228      "last 1 chrome version",
229      "last 1 firefox version",
230      "last 1 safari version"
231    ]
232  }
233}
234    - name: Fix up git URLs
235      run: echo -e '[url "https://github.com/"]\n  insteadOf = "git://github.com/"' >> ~/.gitconfig
236git config --global url."https://github.com/".insteadOf git://github.com/
237

You can also use SSH, but GitHub Security reminds us that, as of March 15th, 2022, GitHub stopped accepting DSA keys. RSA keys uploaded after Nov 2, 2021 will work only with SHA-2 signatures.
The deprecated MACs, ciphers, and unencrypted Git protocol are permanently disabled.

So this (with the right key) would work:

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9  steps:
10  - name: Checkout
11    uses: actions/checkout@v2
12
13  - id: vars
14    run: |
15      if [ '${{ github.ref }}' == 'refs/heads/master' ]; then echo "::set-output name=environment::prod_stackstream" ; echo "::set-output name=api-url::api" ; elif [ '${{ github.ref }}' == 'refs/heads/staging' ]; then echo "::set-output name=environment::staging_stackstream"  ; echo "::set-output name=api-url::stagingapi" ; else echo "::set-output name=environment::dev_stackstream" ; echo "::set-output name=api-url::devapi" ; fi
16
17  - uses: pCYSl5EDgo/cat@master
18    id: slack
19    with:
20      path: .github/workflows/slack.txt
21
22  - name: Slack Start Notification
23    uses: 8398a7/action-slack@v3
24    env:
25      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
26      ENVIRONMENT: '`${{ steps.vars.outputs.environment }}`'
27      COLOR: good
28      STATUS: '`Started`'
29    with:
30      status: custom
31      fields: workflow,job,commit,repo,ref,author,took
32      custom_payload: |
33        ${{ steps.slack.outputs.text }}
34
35  - name: Installing modules
36    env:
37      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
38    run: yarn install
39
40  - name: Create Frontend Build
41    env:
42      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
43    run: yarn build
44
45  - name: Deploy to Frontend Server DEV
46    if: ${{ contains(github.ref, 'dev') }}
47    uses: easingthemes/ssh-deploy@v2.1.5
48    env:
49      SSH_PRIVATE_KEY: ${{ secrets.DEV_KEY }}
50      ARGS: '-rltgoDzvO --delete'
51      SOURCE: 'deploy/'
52      REMOTE_HOST: ${{ secrets.DEV_HOST }}
53      REMOTE_USER: plyfolio-dev
54      TARGET: '/home/plyfolio-dev/${{ steps.vars.outputs.environment }}/fe/deploy'
55   {
56  "name": "stackstream-fe",
57  "version": "1.0.0",
58  "authors": [
59    "fayyaznofal@gmail.com"
60  ],
61  "private": true,
62  "dependencies": {
63    "@fortawesome/fontawesome-svg-core": "^1.2.34",
64    "@fortawesome/free-solid-svg-icons": "^5.15.2",
65    "@fortawesome/react-fontawesome": "^0.1.14",
66    "@fullcalendar/bootstrap": "^5.5.0",
67    "@fullcalendar/core": "^5.5.0",
68    "@fullcalendar/daygrid": "^5.5.0",
69    "@fullcalendar/interaction": "^5.5.0",
70    "@fullcalendar/react": "^5.5.0",
71    "@lourenci/react-kanban": "^2.1.0",
72    "@redux-saga/simple-saga-monitor": "^1.1.2",
73    "@testing-library/jest-dom": "^5.11.9",
74    "@testing-library/react": "^11.2.3",
75    "@testing-library/user-event": "^12.6.0",
76    "@toast-ui/react-chart": "^1.0.2",
77    "@types/jest": "^26.0.14",
78    "@types/node": "^14.10.3",
79    "@types/react": "^16.9.49",
80    "@types/react-dom": "^16.9.8",
81    "@vtaits/react-color-picker": "^0.1.1",
82    "apexcharts": "^3.23.1",
83    "availity-reactstrap-validation": "^2.7.0",
84    "axios": "^0.21.1",
85    "axios-mock-adapter": "^1.19.0",
86    "axios-progress-bar": "^1.2.0",
87    "bootstrap": "^5.0.0-beta2",
88    "chart.js": "^2.9.4",
89    "chartist": "^0.11.4",
90    "classnames": "^2.2.6",
91    "components": "^0.1.0",
92    "dotenv": "^8.2.0",
93    "draft-js": "^0.11.7",
94    "echarts": "^4.9.0",
95    "echarts-for-react": "^2.0.16",
96    "firebase": "^8.2.3",
97    "google-maps-react": "^2.0.6",
98    "history": "^4.10.1",
99    "i": "^0.3.6",
100    "i18next": "^19.8.4",
101    "i18next-browser-languagedetector": "^6.0.1",
102    "jsonwebtoken": "^8.5.1",
103    "leaflet": "^1.7.1",
104    "lodash": "^4.17.21",
105    "lodash.clonedeep": "^4.5.0",
106    "lodash.get": "^4.4.2",
107    "metismenujs": "^1.2.1",
108    "mkdirp": "^1.0.4",
109    "moment": "2.29.1",
110    "moment-timezone": "^0.5.32",
111    "nouislider-react": "^3.3.9",
112    "npm": "^7.6.3",
113    "prop-types": "^15.7.2",
114    "query-string": "^6.14.0",
115    "react": "^16.13.1",
116    "react-apexcharts": "^1.3.7",
117    "react-auth-code-input": "^1.0.0",
118    "react-avatar": "^3.10.0",
119    "react-bootstrap": "^1.5.0",
120    "react-bootstrap-editable": "^0.8.2",
121    "react-bootstrap-sweetalert": "^5.2.0",
122    "react-bootstrap-table-next": "^4.0.3",
123    "react-bootstrap-table2-editor": "^1.4.0",
124    "react-bootstrap-table2-paginator": "^2.1.2",
125    "react-bootstrap-table2-toolkit": "^2.1.3",
126    "react-chartist": "^0.14.3",
127    "react-chartjs-2": "^2.11.1",
128    "react-color": "^2.19.3",
129    "react-confirm-alert": "^2.7.0",
130    "react-content-loader": "^6.0.1",
131    "react-countdown": "^2.3.1",
132    "react-countup": "^4.3.3",
133    "react-cropper": "^2.1.4",
134    "react-data-table-component": "^6.11.8",
135    "react-date-picker": "^8.0.6",
136    "react-datepicker": "^3.4.1",
137    "react-dom": "^16.13.1",
138    "react-draft-wysiwyg": "^1.14.5",
139    "react-drag-listview": "^0.1.8",
140    "react-drawer": "^1.3.4",
141    "react-dropzone": "^11.2.4",
142    "react-dual-listbox": "^2.0.0",
143    "react-facebook-login": "^4.1.1",
144    "react-flatpickr": "^3.10.6",
145    "react-google-login": "^5.2.2",
146    "react-hook-form": "^7.15.2",
147    "react-i18next": "^11.8.5",
148    "react-icons": "^4.2.0",
149    "react-image-lightbox": "^5.1.1",
150    "react-input-mask": "^2.0.4",
151    "react-jvectormap": "^0.0.16",
152    "react-leaflet": "^3.0.5",
153    "react-meta-tags": "^1.0.1",
154    "react-modal-video": "^1.2.6",
155    "react-notifications": "^1.7.2",
156    "react-number-format": "^4.7.3",
157    "react-perfect-scrollbar": "^1.5.8",
158    "react-rangeslider": "^2.2.0",
159    "react-rating": "^2.0.5",
160    "react-rating-tooltip": "^1.1.6",
161    "react-redux": "^7.2.1",
162    "react-responsive-carousel": "^3.2.11",
163    "react-router-dom": "^5.2.0",
164    "react-script": "^2.0.5",
165    "react-scripts": "3.4.3",
166    "react-select": "^4.3.1",
167    "react-sparklines": "^1.7.0",
168    "react-star-ratings": "^2.3.0",
169    "react-super-responsive-table": "^5.2.0",
170    "react-switch": "^6.0.0",
171    "react-table": "^7.6.3",
172    "react-toastify": "^7.0.3",
173    "react-toastr": "^3.0.0",
174    "react-twitter-auth": "0.0.13",
175    "reactstrap": "^8.8.1",
176    "recharts": "^2.0.8",
177    "redux": "^4.0.5",
178    "redux-saga": "^1.1.3",
179    "reselect": "^4.0.0",
180    "sass": "^1.37.5",
181    "simplebar-react": "^2.3.0",
182    "styled": "^1.0.0",
183    "styled-components": "^5.2.1",
184    "toastr": "^2.1.4",
185    "typescript": "^4.0.2",
186    "universal-cookie": "^4.0.4"
187  },
188  "devDependencies": {
189    "@typescript-eslint/eslint-plugin": "^2.27.0",
190    "@typescript-eslint/parser": "^2.27.0",
191    "@typescript-eslint/typescript-estree": "^4.15.2",
192    "eslint-config-prettier": "^6.10.1",
193    "eslint-plugin-prettier": "^3.1.2",
194    "husky": "^4.2.5",
195    "lint-staged": "^10.1.3",
196    "prettier": "^1.19.1",
197    "react-test-renderer": "^16.13.1",
198    "redux-devtools-extension": "^2.13.8",
199    "redux-mock-store": "^1.5.4"
200  },
201  "scripts": {
202    "start": "react-scripts start",
203    "build": "react-scripts build && mv build ./deploy/build",
204    "build-local": "react-scripts build",
205    "test": "react-scripts test",
206    "eject": "react-scripts eject"
207  },
208  "eslintConfig": {
209    "extends": "react-app"
210  },
211  "husky": {
212    "hooks": {
213      "pre-commit": "lint-staged"
214    }
215  },
216  "lint-staged": {
217    "*.{js,ts,tsx}": [
218      "eslint --fix"
219    ]
220  },
221  "browserslist": {
222    "production": [
223      ">0.2%",
224      "not dead",
225      "not op_mini all"
226    ],
227    "development": [
228      "last 1 chrome version",
229      "last 1 firefox version",
230      "last 1 safari version"
231    ]
232  }
233}
234    - name: Fix up git URLs
235      run: echo -e '[url "https://github.com/"]\n  insteadOf = "git://github.com/"' >> ~/.gitconfig
236git config --global url."https://github.com/".insteadOf git://github.com/
237git config --global url."git@github.com:".insteadOf git://github.com/
238

That will change any git://github.com/ (unencrypted Git protocol) into git@github.com: (SSH URL).

Source https://stackoverflow.com/questions/70663523

QUESTION

Making a JSX syntax for a MockComponent and have it typed with typescript

Asked 2022-Mar-20 at 22:37

Wondering if anybody has some good suggestions on how to crack this. Got this test helper utils I have added some types to:

1import { jest } from '@jest/globals'
2import React from 'react'
3
4// https://learn.reactnativeschool.com/courses/781007/lectures/14173979
5export function mockComponent(moduleName: string, propOverrideFn = (props: Record<string, any>) => ({})) {
6  const RealComponent = jest.requireActual(moduleName) as React.ComponentType<any>
7  const CustomizedComponent = (props: Record<string, any>) => {
8    return React.createElement(
9      'CustomizedComponent',
10      {
11        ...props,
12        ...propOverrideFn(props),
13      },
14      props.children
15    )
16  }
17  CustomizedComponent.propTypes = RealComponent.propTypes
18
19  return CustomizedComponent
20}
21

So currently I can call it like this

1import { jest } from '@jest/globals'
2import React from 'react'
3
4// https://learn.reactnativeschool.com/courses/781007/lectures/14173979
5export function mockComponent(moduleName: string, propOverrideFn = (props: Record<string, any>) => ({})) {
6  const RealComponent = jest.requireActual(moduleName) as React.ComponentType<any>
7  const CustomizedComponent = (props: Record<string, any>) => {
8    return React.createElement(
9      'CustomizedComponent',
10      {
11        ...props,
12        ...propOverrideFn(props),
13      },
14      props.children
15    )
16  }
17  CustomizedComponent.propTypes = RealComponent.propTypes
18
19  return CustomizedComponent
20}
21jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
22  return mockComponent('react-native/Libraries/Components/Touchable/TouchableOpacity', (props) => {
23    return {
24      onPress: props.disabled ? () => {} : props.onPress
25    }
26  })
27})
28

But I would like to be able to call it more like

1import { jest } from '@jest/globals'
2import React from 'react'
3
4// https://learn.reactnativeschool.com/courses/781007/lectures/14173979
5export function mockComponent(moduleName: string, propOverrideFn = (props: Record<string, any>) => ({})) {
6  const RealComponent = jest.requireActual(moduleName) as React.ComponentType<any>
7  const CustomizedComponent = (props: Record<string, any>) => {
8    return React.createElement(
9      'CustomizedComponent',
10      {
11        ...props,
12        ...propOverrideFn(props),
13      },
14      props.children
15    )
16  }
17  CustomizedComponent.propTypes = RealComponent.propTypes
18
19  return CustomizedComponent
20}
21jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
22  return mockComponent('react-native/Libraries/Components/Touchable/TouchableOpacity', (props) => {
23    return {
24      onPress: props.disabled ? () => {} : props.onPress
25    }
26  })
27})
28
29jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
30  return <MockComponent 
31          module='TouchableOpacity' 
32          onPress={props => props.disabled ? () => {} : props.onPress}
33         />
34})
35
36

or

1import { jest } from '@jest/globals'
2import React from 'react'
3
4// https://learn.reactnativeschool.com/courses/781007/lectures/14173979
5export function mockComponent(moduleName: string, propOverrideFn = (props: Record<string, any>) => ({})) {
6  const RealComponent = jest.requireActual(moduleName) as React.ComponentType<any>
7  const CustomizedComponent = (props: Record<string, any>) => {
8    return React.createElement(
9      'CustomizedComponent',
10      {
11        ...props,
12        ...propOverrideFn(props),
13      },
14      props.children
15    )
16  }
17  CustomizedComponent.propTypes = RealComponent.propTypes
18
19  return CustomizedComponent
20}
21jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
22  return mockComponent('react-native/Libraries/Components/Touchable/TouchableOpacity', (props) => {
23    return {
24      onPress: props.disabled ? () => {} : props.onPress
25    }
26  })
27})
28
29jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
30  return <MockComponent 
31          module='TouchableOpacity' 
32          onPress={props => props.disabled ? () => {} : props.onPress}
33         />
34})
35
36jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
37 return <MockComponent 
38          module='TouchableOpacity'
39          propOverride={props => ({onPress: props.disabled ? () => {} : props.onPress, ...props})}
40        />
41})
42

ANSWER

Answered 2022-Mar-20 at 22:37

If you look at React without JSX, you'll see that the XML-inspired syntax (<MockComponent />) is just short for React.createElement('MockComponent').

Right now, if you renamed mockComponent to MockComponent and tried using the angle bracket syntax, the first issue is that your function receives two arguments. React components are either class components that take one constructor argument (props) or functional components that take one argument (again, props). The second issue is that your function returns a React functional component, when it needs to return a rendered React element.

One way to fix this issue is to convert mockComponent into a React functional component and make module and propOverride props of the FC.

1import { jest } from '@jest/globals'
2import React from 'react'
3
4// https://learn.reactnativeschool.com/courses/781007/lectures/14173979
5export function mockComponent(moduleName: string, propOverrideFn = (props: Record&lt;string, any&gt;) =&gt; ({})) {
6  const RealComponent = jest.requireActual(moduleName) as React.ComponentType&lt;any&gt;
7  const CustomizedComponent = (props: Record&lt;string, any&gt;) =&gt; {
8    return React.createElement(
9      'CustomizedComponent',
10      {
11        ...props,
12        ...propOverrideFn(props),
13      },
14      props.children
15    )
16  }
17  CustomizedComponent.propTypes = RealComponent.propTypes
18
19  return CustomizedComponent
20}
21jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () =&gt; {
22  return mockComponent('react-native/Libraries/Components/Touchable/TouchableOpacity', (props) =&gt; {
23    return {
24      onPress: props.disabled ? () =&gt; {} : props.onPress
25    }
26  })
27})
28
29jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () =&gt; {
30  return &lt;MockComponent 
31          module='TouchableOpacity' 
32          onPress={props =&gt; props.disabled ? () =&gt; {} : props.onPress}
33         /&gt;
34})
35
36jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () =&gt; {
37 return &lt;MockComponent 
38          module='TouchableOpacity'
39          propOverride={props =&gt; ({onPress: props.disabled ? () =&gt; {} : props.onPress, ...props})}
40        /&gt;
41})
42// https://learn.reactnativeschool.com/courses/781007/lectures/14173979
43export function MockComponent(props) {
44  const { moduleName, propOverrideFn, ...customComponentProps } = props;
45
46  const RealComponent = jest.requireActual(moduleName) as React.ComponentType&lt;any&gt;
47  const CustomizedComponent = (props: Record&lt;string, any&gt;) =&gt; {
48    return React.createElement(
49      'CustomizedComponent',
50      {
51        ...props,
52        ...propOverrideFn(props),
53      },
54      props.children
55    )
56  }
57  CustomizedComponent.propTypes = RealComponent.propTypes
58
59  return &lt;CustomizedComponent {...customComponentProps} /&gt;
60}
61

The differences are subtle but important. Here I modified MockComponent to take in a singular prop argument to be compatible with React.createElement(). This leads to the issue of how to differentiate props that are meant for the CustomizedComponent and what used to be arguments for mockComponent(). Here, I use the JavaScript destructuring and spread operators to separate module and propOverride from the props intended from CustomizedComponent.

Lastly, I use the JSX spread syntax to pass the arbitrary props intended for CustomizedComponent into CustomizedComponent, and I use angle brackets to render it (instead of returning a function).

I'll leave as an exercise for you to come up with the appropriate TypeScript definition for MockComponent's props. You can simply define it as the union of Record<string, any> and module and propOverride. However, you can get fancy and use a template definition so MockComponent<Toolbar> is a union of module and propOverride and Toolbar's props.

Oh, and I almost forgot. Your Jest call would look like

1import { jest } from '@jest/globals'
2import React from 'react'
3
4// https://learn.reactnativeschool.com/courses/781007/lectures/14173979
5export function mockComponent(moduleName: string, propOverrideFn = (props: Record&lt;string, any&gt;) =&gt; ({})) {
6  const RealComponent = jest.requireActual(moduleName) as React.ComponentType&lt;any&gt;
7  const CustomizedComponent = (props: Record&lt;string, any&gt;) =&gt; {
8    return React.createElement(
9      'CustomizedComponent',
10      {
11        ...props,
12        ...propOverrideFn(props),
13      },
14      props.children
15    )
16  }
17  CustomizedComponent.propTypes = RealComponent.propTypes
18
19  return CustomizedComponent
20}
21jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () =&gt; {
22  return mockComponent('react-native/Libraries/Components/Touchable/TouchableOpacity', (props) =&gt; {
23    return {
24      onPress: props.disabled ? () =&gt; {} : props.onPress
25    }
26  })
27})
28
29jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () =&gt; {
30  return &lt;MockComponent 
31          module='TouchableOpacity' 
32          onPress={props =&gt; props.disabled ? () =&gt; {} : props.onPress}
33         /&gt;
34})
35
36jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () =&gt; {
37 return &lt;MockComponent 
38          module='TouchableOpacity'
39          propOverride={props =&gt; ({onPress: props.disabled ? () =&gt; {} : props.onPress, ...props})}
40        /&gt;
41})
42// https://learn.reactnativeschool.com/courses/781007/lectures/14173979
43export function MockComponent(props) {
44  const { moduleName, propOverrideFn, ...customComponentProps } = props;
45
46  const RealComponent = jest.requireActual(moduleName) as React.ComponentType&lt;any&gt;
47  const CustomizedComponent = (props: Record&lt;string, any&gt;) =&gt; {
48    return React.createElement(
49      'CustomizedComponent',
50      {
51        ...props,
52        ...propOverrideFn(props),
53      },
54      props.children
55    )
56  }
57  CustomizedComponent.propTypes = RealComponent.propTypes
58
59  return &lt;CustomizedComponent {...customComponentProps} /&gt;
60}
61jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () =&gt; {
62    (props) =&gt; {
63        return &lt;MockComponent 
64            module='TouchableOpacity' 
65            onPress={props =&gt; props.disabled ? () =&gt; {} : props.onPress}
66            {...props}
67        /&gt;
68   }
69})
70

Source https://stackoverflow.com/questions/71478707

QUESTION

Can not instantiate proxy of class: System.Net.HttpWebRequest. Could not find a parameterless constructor

Asked 2022-Feb-23 at 12:05

I am upgrading my C# function app from .net 3.1 to 6.0`.

When I run my test cases, I found that, 1 of my test case failed with the below error.

Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: System.Net.HttpWebRequest. Could not find a parameterless constructor.

Basically, I am trying to mock HttpWebRequest and below is my piece of code for that.

1var httpWebRequest = new Mock&lt;HttpWebRequest&gt;();
2

It is working fine in .Net 3.1. I am using Moq version 4.16.1 in both the projects.

ANSWER

Answered 2022-Feb-23 at 10:53

Both HttpWebRequest constructors are obsolete and should not be used. You have to use the static function "Create" to create a new instance of the HttpWebRequest class:

HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("http://www.contoso.com/");

To solve your issue, use the HttpClient class instead. This class has a parameterless constructor.

Source https://stackoverflow.com/questions/71112932

QUESTION

Apache Beam Cloud Dataflow Streaming Stuck Side Input

Asked 2022-Jan-12 at 13:12

I'm currently building PoC Apache Beam pipeline in GCP Dataflow. In this case, I want to create streaming pipeline with main input from PubSub and side input from BigQuery and store processed data back to BigQuery.

Side pipeline code

1side_pipeline = (
2    p
3    | &quot;periodic&quot; &gt;&gt; PeriodicImpulse(fire_interval=3600, apply_windowing=True)
4    | &quot;map to read request&quot; &gt;&gt;
5        beam.Map(lambda x:beam.io.gcp.bigquery.ReadFromBigQueryRequest(table=side_table))
6    | beam.io.ReadAllFromBigQuery()
7)
8

Function with side input code

1side_pipeline = (
2    p
3    | &quot;periodic&quot; &gt;&gt; PeriodicImpulse(fire_interval=3600, apply_windowing=True)
4    | &quot;map to read request&quot; &gt;&gt;
5        beam.Map(lambda x:beam.io.gcp.bigquery.ReadFromBigQueryRequest(table=side_table))
6    | beam.io.ReadAllFromBigQuery()
7)
8def enrich_payload(payload, equipments):
9    id = payload[&quot;id&quot;]
10    for equipment in equipments:
11        if id == equipment[&quot;id&quot;]:
12            payload[&quot;type&quot;] = equipment[&quot;type&quot;]
13            payload[&quot;brand&quot;] = equipment[&quot;brand&quot;]
14            payload[&quot;year&quot;] = equipment[&quot;year&quot;]
15
16            break
17
18    return payload
19

Main pipeline code

1side_pipeline = (
2    p
3    | &quot;periodic&quot; &gt;&gt; PeriodicImpulse(fire_interval=3600, apply_windowing=True)
4    | &quot;map to read request&quot; &gt;&gt;
5        beam.Map(lambda x:beam.io.gcp.bigquery.ReadFromBigQueryRequest(table=side_table))
6    | beam.io.ReadAllFromBigQuery()
7)
8def enrich_payload(payload, equipments):
9    id = payload[&quot;id&quot;]
10    for equipment in equipments:
11        if id == equipment[&quot;id&quot;]:
12            payload[&quot;type&quot;] = equipment[&quot;type&quot;]
13            payload[&quot;brand&quot;] = equipment[&quot;brand&quot;]
14            payload[&quot;year&quot;] = equipment[&quot;year&quot;]
15
16            break
17
18    return payload
19main_pipeline = (
20    p
21    | &quot;read&quot; &gt;&gt; beam.io.ReadFromPubSub(topic=&quot;projects/my-project/topics/topiq&quot;)
22    | &quot;bytes to dict&quot; &gt;&gt; beam.Map(lambda x: json.loads(x.decode(&quot;utf-8&quot;)))
23    | &quot;transform&quot; &gt;&gt; beam.Map(transform_function)
24    | &quot;timestamping&quot; &gt;&gt; beam.Map(lambda src: window.TimestampedValue(
25        src,
26        dt.datetime.fromisoformat(src[&quot;timestamp&quot;]).timestamp()
27    ))
28    | &quot;windowing&quot; &gt;&gt; beam.WindowInto(window.FixedWindows(30))
29)
30
31final_pipeline = (
32    main_pipeline
33    | &quot;enrich data&quot; &gt;&gt; beam.Map(enrich_payload, equipments=beam.pvalue.AsIter(side_pipeline))
34    | &quot;store&quot; &gt;&gt; beam.io.WriteToBigQuery(bq_table)
35)
36
37result = p.run()
38result.wait_until_finish()
39

After deploy it to Dataflow, everything looks fine and no error. But then I noticed that enrich data step has two nodes instead of one.

Dataflow Graph

And also, the side input stuck as you can see it has Elements Added with 21 counts in Input Collections and - value in Elements Added in Output Collections. Enrich data stuck

You can find the full pipeline code here and mock pubsub publisher here

I already follow all instruction in these documentations:

Yet still found this error. Please help me. Thanks!

ANSWER

Answered 2022-Jan-12 at 13:12

Here you have a working example:

1side_pipeline = (
2    p
3    | &quot;periodic&quot; &gt;&gt; PeriodicImpulse(fire_interval=3600, apply_windowing=True)
4    | &quot;map to read request&quot; &gt;&gt;
5        beam.Map(lambda x:beam.io.gcp.bigquery.ReadFromBigQueryRequest(table=side_table))
6    | beam.io.ReadAllFromBigQuery()
7)
8def enrich_payload(payload, equipments):
9    id = payload[&quot;id&quot;]
10    for equipment in equipments:
11        if id == equipment[&quot;id&quot;]:
12            payload[&quot;type&quot;] = equipment[&quot;type&quot;]
13            payload[&quot;brand&quot;] = equipment[&quot;brand&quot;]
14            payload[&quot;year&quot;] = equipment[&quot;year&quot;]
15
16            break
17
18    return payload
19main_pipeline = (
20    p
21    | &quot;read&quot; &gt;&gt; beam.io.ReadFromPubSub(topic=&quot;projects/my-project/topics/topiq&quot;)
22    | &quot;bytes to dict&quot; &gt;&gt; beam.Map(lambda x: json.loads(x.decode(&quot;utf-8&quot;)))
23    | &quot;transform&quot; &gt;&gt; beam.Map(transform_function)
24    | &quot;timestamping&quot; &gt;&gt; beam.Map(lambda src: window.TimestampedValue(
25        src,
26        dt.datetime.fromisoformat(src[&quot;timestamp&quot;]).timestamp()
27    ))
28    | &quot;windowing&quot; &gt;&gt; beam.WindowInto(window.FixedWindows(30))
29)
30
31final_pipeline = (
32    main_pipeline
33    | &quot;enrich data&quot; &gt;&gt; beam.Map(enrich_payload, equipments=beam.pvalue.AsIter(side_pipeline))
34    | &quot;store&quot; &gt;&gt; beam.io.WriteToBigQuery(bq_table)
35)
36
37result = p.run()
38result.wait_until_finish()
39mytopic = &quot;&quot;
40sql = &quot;SELECT station_id, CURRENT_TIMESTAMP() timestamp FROM `bigquery-public-data.austin_bikeshare.bikeshare_stations` LIMIT 10&quot;
41
42def to_bqrequest(e, sql):
43    from apache_beam.io import ReadFromBigQueryRequest
44    yield ReadFromBigQueryRequest(query=sql)
45     
46
47def merge(e, side):
48    for i in side:
49        yield f&quot;Main {e.decode('utf-8')} Side {i}&quot;
50
51pubsub = p | &quot;Read PubSub topic&quot; &gt;&gt; ReadFromPubSub(topic=mytopic)
52
53side_pcol = (p | PeriodicImpulse(fire_interval=300, apply_windowing=False)
54               | &quot;ApplyGlobalWindow&quot; &gt;&gt; WindowInto(window.GlobalWindows(),
55                                           trigger=trigger.Repeatedly(trigger.AfterProcessingTime(5)),
56                                           accumulation_mode=trigger.AccumulationMode.DISCARDING)
57               | &quot;To BQ Request&quot; &gt;&gt; ParDo(to_bqrequest, sql=sql)
58               | ReadAllFromBigQuery()
59            )
60
61final = (pubsub | &quot;Merge&quot; &gt;&gt; ParDo(merge, side=beam.pvalue.AsList(side_pcol))
62                | Map(logging.info)
63        )                    
64    
65p.run()
66

Note this uses a GlobalWindow (so that both inputs have the same window). I used a processing time trigger so that the pane contains multiple rows. 5 was chosen arbitrarily, using 1 would work too.

Please note matching the data between side and main inputs is non deterministic, and you may see fluctuating values from older fired panes.

In theory, using FixedWindows should fix this, but I cannot get the FixedWindows to work.

Source https://stackoverflow.com/questions/70561769

QUESTION

How to compare file paths from JsonConfigurationSources and Directory.GetFiles properly?

Asked 2021-Dec-20 at 04:22

I created an extension method to add all JSON configuration files to the IConfigurationBuilder

1public static class IConfigurationBuilderExtensions
2{
3    public static IConfigurationBuilder AddJsonFilesFromDirectory(
4        this IConfigurationBuilder configurationBuilder,
5        IFileSystem fileSystem,
6        string pathToDirectory,
7        bool fileIsOptional,
8        bool reloadConfigurationOnFileChange,
9        string searchPattern = &quot;*.json&quot;,
10        SearchOption directorySearchOption = SearchOption.AllDirectories)
11    {
12        var jsonFilePaths = fileSystem.Directory.EnumerateFiles(pathToDirectory, searchPattern, directorySearchOption);
13
14        foreach (var jsonFilePath in jsonFilePaths)
15        {
16            configurationBuilder.AddJsonFile(jsonFilePath, fileIsOptional, reloadConfigurationOnFileChange);
17        }
18
19        return configurationBuilder;
20    }
21}
22

and want to create tests for it using xUnit. Based on

How do you mock out the file system in C# for unit testing?

I installed the packages System.IO.Abstractions and System.IO.Abstractions.TestingHelpers and started to test that JSON files from directories have been added

1public static class IConfigurationBuilderExtensions
2{
3    public static IConfigurationBuilder AddJsonFilesFromDirectory(
4        this IConfigurationBuilder configurationBuilder,
5        IFileSystem fileSystem,
6        string pathToDirectory,
7        bool fileIsOptional,
8        bool reloadConfigurationOnFileChange,
9        string searchPattern = &quot;*.json&quot;,
10        SearchOption directorySearchOption = SearchOption.AllDirectories)
11    {
12        var jsonFilePaths = fileSystem.Directory.EnumerateFiles(pathToDirectory, searchPattern, directorySearchOption);
13
14        foreach (var jsonFilePath in jsonFilePaths)
15        {
16            configurationBuilder.AddJsonFile(jsonFilePath, fileIsOptional, reloadConfigurationOnFileChange);
17        }
18
19        return configurationBuilder;
20    }
21}
22public sealed class IConfigurationBuilderExtensionsTests
23{
24    private const string DirectoryRootPath = &quot;./&quot;;
25    
26    private readonly MockFileSystem _fileSystem;
27
28    public IConfigurationBuilderExtensionsTests()
29    {
30        _fileSystem = new MockFileSystem(new[]
31            {
32                &quot;text.txt&quot;, 
33                &quot;config.json&quot;, 
34                &quot;dir/foo.json&quot;, 
35                &quot;dir/bar.xml&quot;, 
36                &quot;dir/sub/deeper/config.json&quot;
37            }
38            .Select(filePath =&gt; Path.Combine(DirectoryRootPath, filePath))
39            .ToDictionary(
40            filePath =&gt; filePath, 
41            _ =&gt; new MockFileData(string.Empty)));
42    }
43    
44    [Theory]
45    [InlineData(&quot;*.json&quot;, SearchOption.AllDirectories)]
46    [InlineData(&quot;*.json&quot;, SearchOption.TopDirectoryOnly)]
47    // ... more theories go here ...
48    public void ItShouldAddJsonFilesFromDirectory(string searchPattern, SearchOption searchOption)
49    {
50        var addedJsonFilePaths = new ConfigurationBuilder()
51            .AddJsonFilesFromDirectory(_fileSystem, DirectoryRootPath, true, true, searchPattern, searchOption)
52            .Sources
53            .OfType&lt;JsonConfigurationSource&gt;()
54            .Select(jsonConfigurationSource =&gt; jsonConfigurationSource.Path)
55            .ToArray();
56        
57        var jsonFilePathsFromTopDirectory = _fileSystem.Directory.GetFiles(DirectoryRootPath, searchPattern, searchOption);
58        
59        Assert.True(addedJsonFilePaths.Length == jsonFilePathsFromTopDirectory.Length);
60    
61        for (int i = 0; i &lt; addedJsonFilePaths.Length; i++)
62        {
63            Assert.Equal(
64                jsonFilePathsFromTopDirectory[i],
65                Path.DirectorySeparatorChar + addedJsonFilePaths[i]);
66        }
67    }
68}
69

The tests are passing but I would like to know if I could get in trouble when prepending Path.DirectorySeparatorChar to addedJsonFilePaths[i].

The problem is that

  • jsonFilePathsFromTopDirectory[i] returns "/config.json"
  • addedJsonFilePaths[i] returns "config.json"

so I have to prepend a slash at the beginning. Do you have any suggestions how to improve this / avoid later problems?

ANSWER

Answered 2021-Dec-19 at 09:24

The logic of comparing files seems alright, I don't find any outstanding problem with it, it is ok to prepend the "/" to match what you need. Could be even better if you could use the System.IO.Path.DirectorySeparatorChar for the directory root path as well, so if you run on windows or Linux you will have no issues.

But there may be a conceptual problem with what you are doing. To my understanding you aim to verify existence of specific configuration files required for your program to work right, if those files are missing than the program should fail. But that kind of failure due to missing configuration files, is an expected and valid result of your code. Yet, you unit-test this as if missing files should fail the test, as if missing files are an indication that something wrong with your code, this is wrong.

Missing files are not indication of your code not working correct and Unit-test should not be used as a validator to make sure the files exist prior executing the program, you will likely agree that unit-test is not part of the actual process and it should only aim to test your code and not preconditions, the test should compare an expected result (mock result of your code) vs. actual result and certainly not meant to become part of the code. That unit test looks like a validator that should be in the code.

So unless those files are produced by your specific code (and not the deployment) there is no sense testing that. In such case you need to create a configuration validator code - and your unit test could test that instead. So it will test that the validator expected result with a mock input you provide. But the thing here is that you would know that you only testing the validation logic and not the actual existence of the files.

Source https://stackoverflow.com/questions/70378711

QUESTION

How to get preview in composable functions that depend on a view model?

Asked 2021-Dec-16 at 21:53
Problem description

I would like to have the preview of my HomeScreen composable function in my HomeScreenPrevieiw preview function. However this is not being possible to do because I am getting the following error:

1java.lang.IllegalStateException: ViewModels creation is not supported in Preview
2    at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
3    at androidx.lifecycle.ViewModelProvider.&lt;init&gt;(ViewModelProvider.kt:105)
4    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
5    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
6    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
7    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    ...
11
My code

This is my HomeScreen code:

1java.lang.IllegalStateException: ViewModels creation is not supported in Preview
2    at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
3    at androidx.lifecycle.ViewModelProvider.&lt;init&gt;(ViewModelProvider.kt:105)
4    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
5    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
6    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
7    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    ...
11@Composable
12fun HomeScreen(
13    viewModel: HomeViewModel = hiltViewModel(),
14    navigateToDetailsAction: () -&gt; Unit,
15    openCardDetailsAction: (Int) -&gt; Unit
16) {
17    val cities = viewModel.cities.observeAsState(listOf())
18    Scaffold(
19        topBar = { HomeAppBar() },
20        floatingActionButton = { HomeFab(navigateToDetailsAction) }
21    ) {
22        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
23    }
24}
25

This is the code for my preview function:

1java.lang.IllegalStateException: ViewModels creation is not supported in Preview
2    at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
3    at androidx.lifecycle.ViewModelProvider.&lt;init&gt;(ViewModelProvider.kt:105)
4    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
5    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
6    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
7    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    ...
11@Composable
12fun HomeScreen(
13    viewModel: HomeViewModel = hiltViewModel(),
14    navigateToDetailsAction: () -&gt; Unit,
15    openCardDetailsAction: (Int) -&gt; Unit
16) {
17    val cities = viewModel.cities.observeAsState(listOf())
18    Scaffold(
19        topBar = { HomeAppBar() },
20        floatingActionButton = { HomeFab(navigateToDetailsAction) }
21    ) {
22        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
23    }
24}
25@Preview
26@Composable
27private fun HomeScreenPreview() {
28    HomeScreen(navigateToDetailsAction = {}, openCardDetailsAction = {})
29}
30

My view model:

1java.lang.IllegalStateException: ViewModels creation is not supported in Preview
2    at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
3    at androidx.lifecycle.ViewModelProvider.&lt;init&gt;(ViewModelProvider.kt:105)
4    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
5    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
6    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
7    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    ...
11@Composable
12fun HomeScreen(
13    viewModel: HomeViewModel = hiltViewModel(),
14    navigateToDetailsAction: () -&gt; Unit,
15    openCardDetailsAction: (Int) -&gt; Unit
16) {
17    val cities = viewModel.cities.observeAsState(listOf())
18    Scaffold(
19        topBar = { HomeAppBar() },
20        floatingActionButton = { HomeFab(navigateToDetailsAction) }
21    ) {
22        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
23    }
24}
25@Preview
26@Composable
27private fun HomeScreenPreview() {
28    HomeScreen(navigateToDetailsAction = {}, openCardDetailsAction = {})
29}
30@HiltViewModel
31class HomeViewModel @Inject constructor(repository: CityRepository) : ViewModel() {
32    val cities: LiveData&lt;List&lt;City&gt;&gt; = repository.allCities.asLiveData()
33}
34

Repository:

1java.lang.IllegalStateException: ViewModels creation is not supported in Preview
2    at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
3    at androidx.lifecycle.ViewModelProvider.&lt;init&gt;(ViewModelProvider.kt:105)
4    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
5    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
6    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
7    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    ...
11@Composable
12fun HomeScreen(
13    viewModel: HomeViewModel = hiltViewModel(),
14    navigateToDetailsAction: () -&gt; Unit,
15    openCardDetailsAction: (Int) -&gt; Unit
16) {
17    val cities = viewModel.cities.observeAsState(listOf())
18    Scaffold(
19        topBar = { HomeAppBar() },
20        floatingActionButton = { HomeFab(navigateToDetailsAction) }
21    ) {
22        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
23    }
24}
25@Preview
26@Composable
27private fun HomeScreenPreview() {
28    HomeScreen(navigateToDetailsAction = {}, openCardDetailsAction = {})
29}
30@HiltViewModel
31class HomeViewModel @Inject constructor(repository: CityRepository) : ViewModel() {
32    val cities: LiveData&lt;List&lt;City&gt;&gt; = repository.allCities.asLiveData()
33}
34@ViewModelScoped
35class CityRepository @Inject constructor(appDatabase: AppDatabase) {
36    private val dao by lazy { appDatabase.getCityDao() }
37
38    val allCities by lazy { dao.getAllCities() }
39
40    suspend fun addCity(city: City) = dao.insert(city)
41
42    suspend fun updateCity(city: City) = dao.update(city)
43
44    suspend fun deleteCity(city: City) = dao.delete(city)
45
46    suspend fun getCityById(id: Int) = dao.getCityById(id)
47
48}
49

AppDatabase:

1java.lang.IllegalStateException: ViewModels creation is not supported in Preview
2    at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
3    at androidx.lifecycle.ViewModelProvider.&lt;init&gt;(ViewModelProvider.kt:105)
4    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
5    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
6    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
7    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    ...
11@Composable
12fun HomeScreen(
13    viewModel: HomeViewModel = hiltViewModel(),
14    navigateToDetailsAction: () -&gt; Unit,
15    openCardDetailsAction: (Int) -&gt; Unit
16) {
17    val cities = viewModel.cities.observeAsState(listOf())
18    Scaffold(
19        topBar = { HomeAppBar() },
20        floatingActionButton = { HomeFab(navigateToDetailsAction) }
21    ) {
22        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
23    }
24}
25@Preview
26@Composable
27private fun HomeScreenPreview() {
28    HomeScreen(navigateToDetailsAction = {}, openCardDetailsAction = {})
29}
30@HiltViewModel
31class HomeViewModel @Inject constructor(repository: CityRepository) : ViewModel() {
32    val cities: LiveData&lt;List&lt;City&gt;&gt; = repository.allCities.asLiveData()
33}
34@ViewModelScoped
35class CityRepository @Inject constructor(appDatabase: AppDatabase) {
36    private val dao by lazy { appDatabase.getCityDao() }
37
38    val allCities by lazy { dao.getAllCities() }
39
40    suspend fun addCity(city: City) = dao.insert(city)
41
42    suspend fun updateCity(city: City) = dao.update(city)
43
44    suspend fun deleteCity(city: City) = dao.delete(city)
45
46    suspend fun getCityById(id: Int) = dao.getCityById(id)
47
48}
49@Database(entities = [City::class], version = 2, exportSchema = false)
50abstract class AppDatabase : RoomDatabase() {
51    abstract fun getCityDao() : CityDao
52}
53
My failed attempt

I thought it might be a problem with the view model being passed as the default parameter of my HomeScreen and so I decided to do it this way:

1java.lang.IllegalStateException: ViewModels creation is not supported in Preview
2    at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
3    at androidx.lifecycle.ViewModelProvider.&lt;init&gt;(ViewModelProvider.kt:105)
4    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
5    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
6    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
7    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    ...
11@Composable
12fun HomeScreen(
13    viewModel: HomeViewModel = hiltViewModel(),
14    navigateToDetailsAction: () -&gt; Unit,
15    openCardDetailsAction: (Int) -&gt; Unit
16) {
17    val cities = viewModel.cities.observeAsState(listOf())
18    Scaffold(
19        topBar = { HomeAppBar() },
20        floatingActionButton = { HomeFab(navigateToDetailsAction) }
21    ) {
22        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
23    }
24}
25@Preview
26@Composable
27private fun HomeScreenPreview() {
28    HomeScreen(navigateToDetailsAction = {}, openCardDetailsAction = {})
29}
30@HiltViewModel
31class HomeViewModel @Inject constructor(repository: CityRepository) : ViewModel() {
32    val cities: LiveData&lt;List&lt;City&gt;&gt; = repository.allCities.asLiveData()
33}
34@ViewModelScoped
35class CityRepository @Inject constructor(appDatabase: AppDatabase) {
36    private val dao by lazy { appDatabase.getCityDao() }
37
38    val allCities by lazy { dao.getAllCities() }
39
40    suspend fun addCity(city: City) = dao.insert(city)
41
42    suspend fun updateCity(city: City) = dao.update(city)
43
44    suspend fun deleteCity(city: City) = dao.delete(city)
45
46    suspend fun getCityById(id: Int) = dao.getCityById(id)
47
48}
49@Database(entities = [City::class], version = 2, exportSchema = false)
50abstract class AppDatabase : RoomDatabase() {
51    abstract fun getCityDao() : CityDao
52}
53@Composable
54fun HomeScreen(
55    navigateToDetailsAction: () -&gt; Unit,
56    openCardDetailsAction: (Int) -&gt; Unit
57) {
58    val viewModel: HomeViewModel = hiltViewModel()
59    val cities = viewModel.cities.observeAsState(listOf())
60    Scaffold(
61        topBar = { HomeAppBar() },
62        floatingActionButton = { HomeFab(navigateToDetailsAction) }
63    ) {
64        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
65    }
66}
67

But it still doesn't work (I keep getting the same error), and it's not good for testing as it would prevent me from testing my HomeScreen with a mocked view model.

ANSWER

Answered 2021-Sep-07 at 16:48

This is exactly one of the reasons why the view model is passed with a default value. In the preview, you can pass a test object:

1java.lang.IllegalStateException: ViewModels creation is not supported in Preview
2    at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
3    at androidx.lifecycle.ViewModelProvider.&lt;init&gt;(ViewModelProvider.kt:105)
4    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
5    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
6    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
7    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    ...
11@Composable
12fun HomeScreen(
13    viewModel: HomeViewModel = hiltViewModel(),
14    navigateToDetailsAction: () -&gt; Unit,
15    openCardDetailsAction: (Int) -&gt; Unit
16) {
17    val cities = viewModel.cities.observeAsState(listOf())
18    Scaffold(
19        topBar = { HomeAppBar() },
20        floatingActionButton = { HomeFab(navigateToDetailsAction) }
21    ) {
22        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
23    }
24}
25@Preview
26@Composable
27private fun HomeScreenPreview() {
28    HomeScreen(navigateToDetailsAction = {}, openCardDetailsAction = {})
29}
30@HiltViewModel
31class HomeViewModel @Inject constructor(repository: CityRepository) : ViewModel() {
32    val cities: LiveData&lt;List&lt;City&gt;&gt; = repository.allCities.asLiveData()
33}
34@ViewModelScoped
35class CityRepository @Inject constructor(appDatabase: AppDatabase) {
36    private val dao by lazy { appDatabase.getCityDao() }
37
38    val allCities by lazy { dao.getAllCities() }
39
40    suspend fun addCity(city: City) = dao.insert(city)
41
42    suspend fun updateCity(city: City) = dao.update(city)
43
44    suspend fun deleteCity(city: City) = dao.delete(city)
45
46    suspend fun getCityById(id: Int) = dao.getCityById(id)
47
48}
49@Database(entities = [City::class], version = 2, exportSchema = false)
50abstract class AppDatabase : RoomDatabase() {
51    abstract fun getCityDao() : CityDao
52}
53@Composable
54fun HomeScreen(
55    navigateToDetailsAction: () -&gt; Unit,
56    openCardDetailsAction: (Int) -&gt; Unit
57) {
58    val viewModel: HomeViewModel = hiltViewModel()
59    val cities = viewModel.cities.observeAsState(listOf())
60    Scaffold(
61        topBar = { HomeAppBar() },
62        floatingActionButton = { HomeFab(navigateToDetailsAction) }
63    ) {
64        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
65    }
66}
67@Preview
68@Composable
69private fun HomeScreenPreview() {
70    val viewModel = HomeViewModel()
71    // setup viewModel as you need it to be in the preview
72    HomeScreen(viewModel = viewModel, navigateToDetailsAction = {}, openCardDetailsAction = {})
73}
74

Since you have a repository, you can do the same thing you would do to test the view model.

  1. Create interface for CityRepository
1java.lang.IllegalStateException: ViewModels creation is not supported in Preview
2    at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
3    at androidx.lifecycle.ViewModelProvider.&lt;init&gt;(ViewModelProvider.kt:105)
4    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
5    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
6    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
7    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    ...
11@Composable
12fun HomeScreen(
13    viewModel: HomeViewModel = hiltViewModel(),
14    navigateToDetailsAction: () -&gt; Unit,
15    openCardDetailsAction: (Int) -&gt; Unit
16) {
17    val cities = viewModel.cities.observeAsState(listOf())
18    Scaffold(
19        topBar = { HomeAppBar() },
20        floatingActionButton = { HomeFab(navigateToDetailsAction) }
21    ) {
22        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
23    }
24}
25@Preview
26@Composable
27private fun HomeScreenPreview() {
28    HomeScreen(navigateToDetailsAction = {}, openCardDetailsAction = {})
29}
30@HiltViewModel
31class HomeViewModel @Inject constructor(repository: CityRepository) : ViewModel() {
32    val cities: LiveData&lt;List&lt;City&gt;&gt; = repository.allCities.asLiveData()
33}
34@ViewModelScoped
35class CityRepository @Inject constructor(appDatabase: AppDatabase) {
36    private val dao by lazy { appDatabase.getCityDao() }
37
38    val allCities by lazy { dao.getAllCities() }
39
40    suspend fun addCity(city: City) = dao.insert(city)
41
42    suspend fun updateCity(city: City) = dao.update(city)
43
44    suspend fun deleteCity(city: City) = dao.delete(city)
45
46    suspend fun getCityById(id: Int) = dao.getCityById(id)
47
48}
49@Database(entities = [City::class], version = 2, exportSchema = false)
50abstract class AppDatabase : RoomDatabase() {
51    abstract fun getCityDao() : CityDao
52}
53@Composable
54fun HomeScreen(
55    navigateToDetailsAction: () -&gt; Unit,
56    openCardDetailsAction: (Int) -&gt; Unit
57) {
58    val viewModel: HomeViewModel = hiltViewModel()
59    val cities = viewModel.cities.observeAsState(listOf())
60    Scaffold(
61        topBar = { HomeAppBar() },
62        floatingActionButton = { HomeFab(navigateToDetailsAction) }
63    ) {
64        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
65    }
66}
67@Preview
68@Composable
69private fun HomeScreenPreview() {
70    val viewModel = HomeViewModel()
71    // setup viewModel as you need it to be in the preview
72    HomeScreen(viewModel = viewModel, navigateToDetailsAction = {}, openCardDetailsAction = {})
73}
74interface CityRepositoryI {
75    val allCities: List&lt;City&gt;
76
77    suspend fun addCity(city: City)
78    suspend fun updateCity(city: City)
79    suspend fun deleteCity(city: City)
80    suspend fun getCityById(id: Int)
81}
82
  1. Implement it for CityRepository:
1java.lang.IllegalStateException: ViewModels creation is not supported in Preview
2    at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
3    at androidx.lifecycle.ViewModelProvider.&lt;init&gt;(ViewModelProvider.kt:105)
4    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
5    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
6    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
7    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    ...
11@Composable
12fun HomeScreen(
13    viewModel: HomeViewModel = hiltViewModel(),
14    navigateToDetailsAction: () -&gt; Unit,
15    openCardDetailsAction: (Int) -&gt; Unit
16) {
17    val cities = viewModel.cities.observeAsState(listOf())
18    Scaffold(
19        topBar = { HomeAppBar() },
20        floatingActionButton = { HomeFab(navigateToDetailsAction) }
21    ) {
22        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
23    }
24}
25@Preview
26@Composable
27private fun HomeScreenPreview() {
28    HomeScreen(navigateToDetailsAction = {}, openCardDetailsAction = {})
29}
30@HiltViewModel
31class HomeViewModel @Inject constructor(repository: CityRepository) : ViewModel() {
32    val cities: LiveData&lt;List&lt;City&gt;&gt; = repository.allCities.asLiveData()
33}
34@ViewModelScoped
35class CityRepository @Inject constructor(appDatabase: AppDatabase) {
36    private val dao by lazy { appDatabase.getCityDao() }
37
38    val allCities by lazy { dao.getAllCities() }
39
40    suspend fun addCity(city: City) = dao.insert(city)
41
42    suspend fun updateCity(city: City) = dao.update(city)
43
44    suspend fun deleteCity(city: City) = dao.delete(city)
45
46    suspend fun getCityById(id: Int) = dao.getCityById(id)
47
48}
49@Database(entities = [City::class], version = 2, exportSchema = false)
50abstract class AppDatabase : RoomDatabase() {
51    abstract fun getCityDao() : CityDao
52}
53@Composable
54fun HomeScreen(
55    navigateToDetailsAction: () -&gt; Unit,
56    openCardDetailsAction: (Int) -&gt; Unit
57) {
58    val viewModel: HomeViewModel = hiltViewModel()
59    val cities = viewModel.cities.observeAsState(listOf())
60    Scaffold(
61        topBar = { HomeAppBar() },
62        floatingActionButton = { HomeFab(navigateToDetailsAction) }
63    ) {
64        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
65    }
66}
67@Preview
68@Composable
69private fun HomeScreenPreview() {
70    val viewModel = HomeViewModel()
71    // setup viewModel as you need it to be in the preview
72    HomeScreen(viewModel = viewModel, navigateToDetailsAction = {}, openCardDetailsAction = {})
73}
74interface CityRepositoryI {
75    val allCities: List&lt;City&gt;
76
77    suspend fun addCity(city: City)
78    suspend fun updateCity(city: City)
79    suspend fun deleteCity(city: City)
80    suspend fun getCityById(id: Int)
81}
82@ViewModelScoped
83class CityRepository @Inject constructor(appDatabase: AppDatabase) : CityRepositoryI {
84    private val dao by lazy { appDatabase.getCityDao() }
85
86    override val allCities by lazy { dao.getAllCities() }
87
88    override suspend fun addCity(city: City) = dao.insert(city)
89
90    override suspend fun updateCity(city: City) = dao.update(city)
91
92    override suspend fun deleteCity(city: City) = dao.delete(city)
93
94    override suspend fun getCityById(id: Int) = dao.getCityById(id)
95}
96
  1. Create FakeCityRepository for testing purposes:
1java.lang.IllegalStateException: ViewModels creation is not supported in Preview
2    at androidx.compose.ui.tooling.ComposeViewAdapter$FakeViewModelStoreOwner$1.getViewModelStore(ComposeViewAdapter.kt:709)
3    at androidx.lifecycle.ViewModelProvider.&lt;init&gt;(ViewModelProvider.kt:105)
4    at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:82)
5    at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:72)
6    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreen(HomeScreen.kt:53)
7    at com.example.crud.ui.screens.home.HomeScreenKt.HomeScreenPreview(HomeScreen.kt:43)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    ...
11@Composable
12fun HomeScreen(
13    viewModel: HomeViewModel = hiltViewModel(),
14    navigateToDetailsAction: () -&gt; Unit,
15    openCardDetailsAction: (Int) -&gt; Unit
16) {
17    val cities = viewModel.cities.observeAsState(listOf())
18    Scaffold(
19        topBar = { HomeAppBar() },
20        floatingActionButton = { HomeFab(navigateToDetailsAction) }
21    ) {
22        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
23    }
24}
25@Preview
26@Composable
27private fun HomeScreenPreview() {
28    HomeScreen(navigateToDetailsAction = {}, openCardDetailsAction = {})
29}
30@HiltViewModel
31class HomeViewModel @Inject constructor(repository: CityRepository) : ViewModel() {
32    val cities: LiveData&lt;List&lt;City&gt;&gt; = repository.allCities.asLiveData()
33}
34@ViewModelScoped
35class CityRepository @Inject constructor(appDatabase: AppDatabase) {
36    private val dao by lazy { appDatabase.getCityDao() }
37
38    val allCities by lazy { dao.getAllCities() }
39
40    suspend fun addCity(city: City) = dao.insert(city)
41
42    suspend fun updateCity(city: City) = dao.update(city)
43
44    suspend fun deleteCity(city: City) = dao.delete(city)
45
46    suspend fun getCityById(id: Int) = dao.getCityById(id)
47
48}
49@Database(entities = [City::class], version = 2, exportSchema = false)
50abstract class AppDatabase : RoomDatabase() {
51    abstract fun getCityDao() : CityDao
52}
53@Composable
54fun HomeScreen(
55    navigateToDetailsAction: () -&gt; Unit,
56    openCardDetailsAction: (Int) -&gt; Unit
57) {
58    val viewModel: HomeViewModel = hiltViewModel()
59    val cities = viewModel.cities.observeAsState(listOf())
60    Scaffold(
61        topBar = { HomeAppBar() },
62        floatingActionButton = { HomeFab(navigateToDetailsAction) }
63    ) {
64        HomeContent(cities) { id -&gt; openCardDetailsAction(id) }
65    }
66}
67@Preview
68@Composable
69private fun HomeScreenPreview() {
70    val viewModel = HomeViewModel()
71    // setup viewModel as you need it to be in the preview
72    HomeScreen(viewModel = viewModel, navigateToDetailsAction = {}, openCardDetailsAction = {})
73}
74interface CityRepositoryI {
75    val allCities: List&lt;City&gt;
76
77    suspend fun addCity(city: City)
78    suspend fun updateCity(city: City)
79    suspend fun deleteCity(city: City)
80    suspend fun getCityById(id: Int)
81}
82@ViewModelScoped
83class CityRepository @Inject constructor(appDatabase: AppDatabase) : CityRepositoryI {
84    private val dao by lazy { appDatabase.getCityDao() }
85
86    override val allCities by lazy { dao.getAllCities() }
87
88    override suspend fun addCity(city: City) = dao.insert(city)
89
90    override suspend fun updateCity(city: City) = dao.update(city)
91
92    override suspend fun deleteCity(city: City) = dao.delete(city)
93
94    override suspend fun getCityById(id: Int) = dao.getCityById(id)
95}
96class FakeCityRepository : CityRepositoryI {
97    // predefined cities for testing
98    val cities = listOf(
99        City(1)
100    ).toMutableStateList()
101
102    override val allCities by lazy { cities }
103
104    override suspend fun addCity(city: City) {
105        cities.add(city)
106    }
107
108    override suspend fun updateCity(city: City){
109        val index = cities.indexOfFirst { it.id == city.id }
110        cities[index] = city
111    }
112
113    override suspend fun deleteCity(city: City) {
114        cities.removeAll { it.id == city.id }
115    }
116
117    override suspend fun getCityById(id: Int) = cities.first { it.id == id }
118}
119

So you can pass it into your view model: HomeViewModel(FakeCityRepository())

You can do the same with AppDatabase instead of a repository, it all depends on your needs. Check out more about Hilt testing

p.s. I'm not sure if this will build, since I don't have some of your classes, but you should have caught the idea.

Source https://stackoverflow.com/questions/69089816

QUESTION

v0.8 AggregatorV3Interface.sol , its available in @chainlink/contracts?

Asked 2021-Nov-05 at 21:48

I get a error when i change the version to 0.8 , but works fine with 0.6, how i see the most recent version? , i tried downloaded from npm install @chainlink/contracts --save, but only works with mock mode.

This is my repo: https://github.com/irwingtello/lottery

Compiling contracts... Solc version: 0.8.9 Optimizer: Enabled Runs: 200 EVM Version: Istanbul CompilerError: solc returned the following errors:

ParserError: Source "C:/Users/irwin/.brownie/packages/smartcontractkit/chainlink-brownie-contracts@1.1.1/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol" not found: File not found. --> contracts/Lottery.sol:4:1: | 4 | import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

ERROR: Unable to load project

ANSWER

Answered 2021-Nov-05 at 21:48

"As of 1.2.0 and onward all the releases of this package are going to match the @chainlink/contracts NPM tags So it will look backwards, but we are starting with 0.2.1"

Change: @chainlink=smartcontractkit/chainlink-brownie-contracts@1.1.1 To: @chainlink=smartcontractkit/chainlink-brownie-contracts@0.2.1

https://github.com/smartcontractkit/chainlink-brownie-contracts/tree/v0.2.1

Source https://stackoverflow.com/questions/69819748

QUESTION

Not able to mock a function inside useEffect

Asked 2021-Oct-13 at 08:26

I have a custom hook as below

1export const useUserSearch = () =&gt; {
2  const [options, setOptions] = useState([]);
3  const [searchString, setSearchString] = useState(&quot;&quot;);
4  const [userSearch] = useUserSearchMutation();
5  useEffect(() =&gt; {
6    if (searchString.trim().length &gt; 3) {
7      const searchParams = {
8        orgId: &quot;1&quot;,
9        userId: &quot;1&quot;,
10        searchQuery: searchString.trim(),
11      };
12      userSearch(searchParams)
13        .then((data) =&gt; {
14          setOptions(data);
15        })
16        .catch((err) =&gt; {
17          setOptions([]);
18          console.log(&quot;error&quot;, err);
19        });
20    }
21  }, [searchString, userSearch]);
22  return {
23    options,
24    setSearchString,
25  };
26};
27

and I want to test this hook but am not able to mock userSearch function which is being called inside useEffect. can anybody help? this is my test

1export const useUserSearch = () =&gt; {
2  const [options, setOptions] = useState([]);
3  const [searchString, setSearchString] = useState(&quot;&quot;);
4  const [userSearch] = useUserSearchMutation();
5  useEffect(() =&gt; {
6    if (searchString.trim().length &gt; 3) {
7      const searchParams = {
8        orgId: &quot;1&quot;,
9        userId: &quot;1&quot;,
10        searchQuery: searchString.trim(),
11      };
12      userSearch(searchParams)
13        .then((data) =&gt; {
14          setOptions(data);
15        })
16        .catch((err) =&gt; {
17          setOptions([]);
18          console.log(&quot;error&quot;, err);
19        });
20    }
21  }, [searchString, userSearch]);
22  return {
23    options,
24    setSearchString,
25  };
26};
27it('should set state and test function', async () =&gt; {
28    const wrapper = ({ children }) =&gt; (
29        &lt;Provider store={store}&gt;{children}&lt;/Provider&gt;
30    )
31    const { result } = renderHook(
32        () =&gt; useUserSearch(),
33        { wrapper }
34    )
35    await act(async () =&gt; {
36        result.current.setSearchString('abc5')
37    })
38    expect(result.current.options).toEqual(expected)
39})
40

useUserSearchMutation

1export const useUserSearch = () =&gt; {
2  const [options, setOptions] = useState([]);
3  const [searchString, setSearchString] = useState(&quot;&quot;);
4  const [userSearch] = useUserSearchMutation();
5  useEffect(() =&gt; {
6    if (searchString.trim().length &gt; 3) {
7      const searchParams = {
8        orgId: &quot;1&quot;,
9        userId: &quot;1&quot;,
10        searchQuery: searchString.trim(),
11      };
12      userSearch(searchParams)
13        .then((data) =&gt; {
14          setOptions(data);
15        })
16        .catch((err) =&gt; {
17          setOptions([]);
18          console.log(&quot;error&quot;, err);
19        });
20    }
21  }, [searchString, userSearch]);
22  return {
23    options,
24    setSearchString,
25  };
26};
27it('should set state and test function', async () =&gt; {
28    const wrapper = ({ children }) =&gt; (
29        &lt;Provider store={store}&gt;{children}&lt;/Provider&gt;
30    )
31    const { result } = renderHook(
32        () =&gt; useUserSearch(),
33        { wrapper }
34    )
35    await act(async () =&gt; {
36        result.current.setSearchString('abc5')
37    })
38    expect(result.current.options).toEqual(expected)
39})
40import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/query/react';
41export const userSearchAPI = createApi({
42  reducerPath: 'userSearchResult',
43  baseQuery: fetchBaseQuery({baseUrl: process.env.REACT_APP_BASE_URL}),
44  tagTypes: ['Users'],
45  endpoints: build =&gt; ({
46    userSearch: build.mutation({
47      query: body =&gt; ({url: '/org/patient/search', method: 'POST', body}),
48      invalidatesTags: ['Users'],
49    }),
50  }),
51});
52export const {useUserSearchMutation} = userSearchAPI;
53

ANSWER

Answered 2021-Oct-13 at 05:27

Because it's a named export you should return an object in the mock

1export const useUserSearch = () =&gt; {
2  const [options, setOptions] = useState([]);
3  const [searchString, setSearchString] = useState(&quot;&quot;);
4  const [userSearch] = useUserSearchMutation();
5  useEffect(() =&gt; {
6    if (searchString.trim().length &gt; 3) {
7      const searchParams = {
8        orgId: &quot;1&quot;,
9        userId: &quot;1&quot;,
10        searchQuery: searchString.trim(),
11      };
12      userSearch(searchParams)
13        .then((data) =&gt; {
14          setOptions(data);
15        })
16        .catch((err) =&gt; {
17          setOptions([]);
18          console.log(&quot;error&quot;, err);
19        });
20    }
21  }, [searchString, userSearch]);
22  return {
23    options,
24    setSearchString,
25  };
26};
27it('should set state and test function', async () =&gt; {
28    const wrapper = ({ children }) =&gt; (
29        &lt;Provider store={store}&gt;{children}&lt;/Provider&gt;
30    )
31    const { result } = renderHook(
32        () =&gt; useUserSearch(),
33        { wrapper }
34    )
35    await act(async () =&gt; {
36        result.current.setSearchString('abc5')
37    })
38    expect(result.current.options).toEqual(expected)
39})
40import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/query/react';
41export const userSearchAPI = createApi({
42  reducerPath: 'userSearchResult',
43  baseQuery: fetchBaseQuery({baseUrl: process.env.REACT_APP_BASE_URL}),
44  tagTypes: ['Users'],
45  endpoints: build =&gt; ({
46    userSearch: build.mutation({
47      query: body =&gt; ({url: '/org/patient/search', method: 'POST', body}),
48      invalidatesTags: ['Users'],
49    }),
50  }),
51});
52export const {useUserSearchMutation} = userSearchAPI;
53it(&quot;should set state and test function&quot;, async () =&gt; {
54  jest.mock(&quot;./useUserSearchMutation&quot;, () =&gt; ({
55    useUserSearchMutation: () =&gt; [jest.fn().mockResolvedValue(expected)],
56  }));
57  const wrapper = ({ children }) =&gt; (
58...
59});
60

Source https://stackoverflow.com/questions/69469942

QUESTION

pytest/unittest: mock.patch function from module?

Asked 2021-Sep-22 at 07:06

Given a folder structure like such:

1dags/
2  **/
3    code.py
4tests/
5  dags/
6    **/
7      test_code.py
8  conftest.py
9

Where dags serves as the root of the src files, with 'dags/a/b/c.py' imported as 'a.b.c'.

I want to test the following function in code.py:

1dags/
2  **/
3    code.py
4tests/
5  dags/
6    **/
7      test_code.py
8  conftest.py
9from dag_common.connections import get_conn
10from utils.database import dbtypes
11
12def select_records(
13    conn_id: str,
14    sql: str,
15    bindings,
16):
17    conn: dbtypes.Connection = get_conn(conn_id)
18    with conn.cursor() as cursor:
19        cursor.execute(
20            sql, bindings
21        )
22        records = cursor.fetchall()
23    return records
24

But I am faced with the issue that I fail to find a way to patch the get_conn from dag_common.connections. I attempted the following:

(1) Globally in conftest.py
1dags/
2  **/
3    code.py
4tests/
5  dags/
6    **/
7      test_code.py
8  conftest.py
9from dag_common.connections import get_conn
10from utils.database import dbtypes
11
12def select_records(
13    conn_id: str,
14    sql: str,
15    bindings,
16):
17    conn: dbtypes.Connection = get_conn(conn_id)
18    with conn.cursor() as cursor:
19        cursor.execute(
20            sql, bindings
21        )
22        records = cursor.fetchall()
23    return records
24import os
25import sys
26
27# adds dags to sys.path for tests/*.py files to be able to import them
28sys.path.append(os.path.join(os.path.dirname(__file__), &quot;..&quot;, &quot;dags&quot;))
29
30{{fixtures}}
31

Where I have tested the following replacements for {{fixtures}}:

(1.a) - default

1dags/
2  **/
3    code.py
4tests/
5  dags/
6    **/
7      test_code.py
8  conftest.py
9from dag_common.connections import get_conn
10from utils.database import dbtypes
11
12def select_records(
13    conn_id: str,
14    sql: str,
15    bindings,
16):
17    conn: dbtypes.Connection = get_conn(conn_id)
18    with conn.cursor() as cursor:
19        cursor.execute(
20            sql, bindings
21        )
22        records = cursor.fetchall()
23    return records
24import os
25import sys
26
27# adds dags to sys.path for tests/*.py files to be able to import them
28sys.path.append(os.path.join(os.path.dirname(__file__), &quot;..&quot;, &quot;dags&quot;))
29
30{{fixtures}}
31@pytest.fixture(autouse=True, scope=&quot;function&quot;)
32def mock_get_conn():
33    with mock.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
34        yield mock_getter
35

(1.b) - prefixing path with dags

1dags/
2  **/
3    code.py
4tests/
5  dags/
6    **/
7      test_code.py
8  conftest.py
9from dag_common.connections import get_conn
10from utils.database import dbtypes
11
12def select_records(
13    conn_id: str,
14    sql: str,
15    bindings,
16):
17    conn: dbtypes.Connection = get_conn(conn_id)
18    with conn.cursor() as cursor:
19        cursor.execute(
20            sql, bindings
21        )
22        records = cursor.fetchall()
23    return records
24import os
25import sys
26
27# adds dags to sys.path for tests/*.py files to be able to import them
28sys.path.append(os.path.join(os.path.dirname(__file__), &quot;..&quot;, &quot;dags&quot;))
29
30{{fixtures}}
31@pytest.fixture(autouse=True, scope=&quot;function&quot;)
32def mock_get_conn():
33    with mock.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
34        yield mock_getter
35@pytest.fixture(autouse=True, scope=&quot;function&quot;)
36def mock_get_conn():
37    with mock.patch(&quot;dags.dag_common.connections.get_conn&quot;) as mock_getter:
38        yield mock_getter
39

(1.c) - 1.a, with scope="session"

(1.d) - 1.b, with scope="session"

(1.e) - object patching the module itself

1dags/
2  **/
3    code.py
4tests/
5  dags/
6    **/
7      test_code.py
8  conftest.py
9from dag_common.connections import get_conn
10from utils.database import dbtypes
11
12def select_records(
13    conn_id: str,
14    sql: str,
15    bindings,
16):
17    conn: dbtypes.Connection = get_conn(conn_id)
18    with conn.cursor() as cursor:
19        cursor.execute(
20            sql, bindings
21        )
22        records = cursor.fetchall()
23    return records
24import os
25import sys
26
27# adds dags to sys.path for tests/*.py files to be able to import them
28sys.path.append(os.path.join(os.path.dirname(__file__), &quot;..&quot;, &quot;dags&quot;))
29
30{{fixtures}}
31@pytest.fixture(autouse=True, scope=&quot;function&quot;)
32def mock_get_conn():
33    with mock.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
34        yield mock_getter
35@pytest.fixture(autouse=True, scope=&quot;function&quot;)
36def mock_get_conn():
37    with mock.patch(&quot;dags.dag_common.connections.get_conn&quot;) as mock_getter:
38        yield mock_getter
39@pytest.fixture(autouse=True, scope=&quot;function&quot;)
40def mock_get_conn():
41    import dags.dag_common.connections
42    mock_getter = mock.MagicMock()
43    with mock.patch.object(dags.dag_common.connections, 'get_conn', mock_getter):
44        yield mock_getter
45

(1.f) - 1.a, but using pytest-mock fixture

1dags/
2  **/
3    code.py
4tests/
5  dags/
6    **/
7      test_code.py
8  conftest.py
9from dag_common.connections import get_conn
10from utils.database import dbtypes
11
12def select_records(
13    conn_id: str,
14    sql: str,
15    bindings,
16):
17    conn: dbtypes.Connection = get_conn(conn_id)
18    with conn.cursor() as cursor:
19        cursor.execute(
20            sql, bindings
21        )
22        records = cursor.fetchall()
23    return records
24import os
25import sys
26
27# adds dags to sys.path for tests/*.py files to be able to import them
28sys.path.append(os.path.join(os.path.dirname(__file__), &quot;..&quot;, &quot;dags&quot;))
29
30{{fixtures}}
31@pytest.fixture(autouse=True, scope=&quot;function&quot;)
32def mock_get_conn():
33    with mock.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
34        yield mock_getter
35@pytest.fixture(autouse=True, scope=&quot;function&quot;)
36def mock_get_conn():
37    with mock.patch(&quot;dags.dag_common.connections.get_conn&quot;) as mock_getter:
38        yield mock_getter
39@pytest.fixture(autouse=True, scope=&quot;function&quot;)
40def mock_get_conn():
41    import dags.dag_common.connections
42    mock_getter = mock.MagicMock()
43    with mock.patch.object(dags.dag_common.connections, 'get_conn', mock_getter):
44        yield mock_getter
45@pytest.fixture(autouse=True, scope=&quot;function&quot;)
46def mock_get_conn(mocker):
47    with mocker.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
48        yield mock_getter
49

(1.g) - 1.b, but using pytest-mock fixture

(1.h) - 1.a, but using pytest's monkeypatch

1dags/
2  **/
3    code.py
4tests/
5  dags/
6    **/
7      test_code.py
8  conftest.py
9from dag_common.connections import get_conn
10from utils.database import dbtypes
11
12def select_records(
13    conn_id: str,
14    sql: str,
15    bindings,
16):
17    conn: dbtypes.Connection = get_conn(conn_id)
18    with conn.cursor() as cursor:
19        cursor.execute(
20            sql, bindings
21        )
22        records = cursor.fetchall()
23    return records
24import os
25import sys
26
27# adds dags to sys.path for tests/*.py files to be able to import them
28sys.path.append(os.path.join(os.path.dirname(__file__), &quot;..&quot;, &quot;dags&quot;))
29
30{{fixtures}}
31@pytest.fixture(autouse=True, scope=&quot;function&quot;)
32def mock_get_conn():
33    with mock.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
34        yield mock_getter
35@pytest.fixture(autouse=True, scope=&quot;function&quot;)
36def mock_get_conn():
37    with mock.patch(&quot;dags.dag_common.connections.get_conn&quot;) as mock_getter:
38        yield mock_getter
39@pytest.fixture(autouse=True, scope=&quot;function&quot;)
40def mock_get_conn():
41    import dags.dag_common.connections
42    mock_getter = mock.MagicMock()
43    with mock.patch.object(dags.dag_common.connections, 'get_conn', mock_getter):
44        yield mock_getter
45@pytest.fixture(autouse=True, scope=&quot;function&quot;)
46def mock_get_conn(mocker):
47    with mocker.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
48        yield mock_getter
49@pytest.fixture(autouse=True, scope=&quot;function&quot;)
50def mock_get_conn(mocker, monkeypatch):
51    import dags.dag_common.connections
52    mock_getter = mocker.MagicMock()
53    monkeypatch.setattr(dags.dag_common.connections, 'get_conn', mock_getter)
54    yield mock_getter
55
(2) Locally applying mock.patch in the test/as a decorator

(2.a) - decorator @mock.patch("dag_common.connections.get_conn")

1dags/
2  **/
3    code.py
4tests/
5  dags/
6    **/
7      test_code.py
8  conftest.py
9from dag_common.connections import get_conn
10from utils.database import dbtypes
11
12def select_records(
13    conn_id: str,
14    sql: str,
15    bindings,
16):
17    conn: dbtypes.Connection = get_conn(conn_id)
18    with conn.cursor() as cursor:
19        cursor.execute(
20            sql, bindings
21        )
22        records = cursor.fetchall()
23    return records
24import os
25import sys
26
27# adds dags to sys.path for tests/*.py files to be able to import them
28sys.path.append(os.path.join(os.path.dirname(__file__), &quot;..&quot;, &quot;dags&quot;))
29
30{{fixtures}}
31@pytest.fixture(autouse=True, scope=&quot;function&quot;)
32def mock_get_conn():
33    with mock.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
34        yield mock_getter
35@pytest.fixture(autouse=True, scope=&quot;function&quot;)
36def mock_get_conn():
37    with mock.patch(&quot;dags.dag_common.connections.get_conn&quot;) as mock_getter:
38        yield mock_getter
39@pytest.fixture(autouse=True, scope=&quot;function&quot;)
40def mock_get_conn():
41    import dags.dag_common.connections
42    mock_getter = mock.MagicMock()
43    with mock.patch.object(dags.dag_common.connections, 'get_conn', mock_getter):
44        yield mock_getter
45@pytest.fixture(autouse=True, scope=&quot;function&quot;)
46def mock_get_conn(mocker):
47    with mocker.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
48        yield mock_getter
49@pytest.fixture(autouse=True, scope=&quot;function&quot;)
50def mock_get_conn(mocker, monkeypatch):
51    import dags.dag_common.connections
52    mock_getter = mocker.MagicMock()
53    monkeypatch.setattr(dags.dag_common.connections, 'get_conn', mock_getter)
54    yield mock_getter
55    @mock.patch(&quot;dag_common.connections.get_conn&quot;)
56    def test_executes_sql_with_default_bindings(mock_getter, mock_context):
57        # arrange
58        sql = &quot;SELECT * FROM table&quot;
59        records = [RealDictRow(col1=1), RealDictRow(col1=2)]
60        mock_conn = mock_getter.return_value
61        mock_cursor = mock_conn.cursor.return_value
62        mock_cursor.execute.return_value = records
63        # act
64        select_records(conn_id=&quot;orca&quot;, sql=sql, ) # ...
65        # assert
66        mock_cursor.execute.assert_called_once_with(
67            sql, # ...
68        )
69

(2.b) - (2.a) but with "dags." prefix

(2.c) - context manager

1dags/
2  **/
3    code.py
4tests/
5  dags/
6    **/
7      test_code.py
8  conftest.py
9from dag_common.connections import get_conn
10from utils.database import dbtypes
11
12def select_records(
13    conn_id: str,
14    sql: str,
15    bindings,
16):
17    conn: dbtypes.Connection = get_conn(conn_id)
18    with conn.cursor() as cursor:
19        cursor.execute(
20            sql, bindings
21        )
22        records = cursor.fetchall()
23    return records
24import os
25import sys
26
27# adds dags to sys.path for tests/*.py files to be able to import them
28sys.path.append(os.path.join(os.path.dirname(__file__), &quot;..&quot;, &quot;dags&quot;))
29
30{{fixtures}}
31@pytest.fixture(autouse=True, scope=&quot;function&quot;)
32def mock_get_conn():
33    with mock.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
34        yield mock_getter
35@pytest.fixture(autouse=True, scope=&quot;function&quot;)
36def mock_get_conn():
37    with mock.patch(&quot;dags.dag_common.connections.get_conn&quot;) as mock_getter:
38        yield mock_getter
39@pytest.fixture(autouse=True, scope=&quot;function&quot;)
40def mock_get_conn():
41    import dags.dag_common.connections
42    mock_getter = mock.MagicMock()
43    with mock.patch.object(dags.dag_common.connections, 'get_conn', mock_getter):
44        yield mock_getter
45@pytest.fixture(autouse=True, scope=&quot;function&quot;)
46def mock_get_conn(mocker):
47    with mocker.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
48        yield mock_getter
49@pytest.fixture(autouse=True, scope=&quot;function&quot;)
50def mock_get_conn(mocker, monkeypatch):
51    import dags.dag_common.connections
52    mock_getter = mocker.MagicMock()
53    monkeypatch.setattr(dags.dag_common.connections, 'get_conn', mock_getter)
54    yield mock_getter
55    @mock.patch(&quot;dag_common.connections.get_conn&quot;)
56    def test_executes_sql_with_default_bindings(mock_getter, mock_context):
57        # arrange
58        sql = &quot;SELECT * FROM table&quot;
59        records = [RealDictRow(col1=1), RealDictRow(col1=2)]
60        mock_conn = mock_getter.return_value
61        mock_cursor = mock_conn.cursor.return_value
62        mock_cursor.execute.return_value = records
63        # act
64        select_records(conn_id=&quot;orca&quot;, sql=sql, ) # ...
65        # assert
66        mock_cursor.execute.assert_called_once_with(
67            sql, # ...
68        )
69    def test_executes_sql_with_default_bindings(mock_context):
70        # arrange
71        sql = &quot;SELECT * FROM table&quot;
72        records = [RealDictRow(col1=1), RealDictRow(col1=2)]
73        with mock.patch(&quot;dag_common.connections.get_conn&quot;) as mock_getter:
74            mock_conn = mock_getter.return_value
75            mock_cursor = mock_conn.cursor.return_value
76            mock_cursor.execute.return_value = records
77            # act
78            select_records(conn_id=&quot;orca&quot;, sql=sql, ) # ...
79            # assert
80            mock_cursor.execute.assert_called_once_with(
81                sql, # ...
82            )
83

(2.d) - (2.c) but with "dags." prefix


Conclusion

But alas, no matter what solution I pick, the function-to-be-mocked still gets called. I made sure to attempt each solution separatedly from each other, and to kill/clear/restart my pytest-watch process in between attempts.

I feel like this may be related to me meddling with sys.path in conftest.py, because outside of this I feel like I have exhausted all possibilities.

Any idea how I can solve this?

ANSWER

Answered 2021-Sep-22 at 07:06

Yeah. I also fought with this initially when I learned patching and mocking and know how frustrating it is as you seem to be doing everything right, but it does not work. I sympathise with you!

This is actually how mocking of imported stuff works, and once you realise it, it actually makes sense.

The problem is that import works in the way that it makes the imported module available in the context of where your import is.

Lets' assume your code.py module is in 'my_package' folder. Your code is available then as my_package.code. And once you use from dag_common.connections import get_conn in code module - the imported get_conn becomes available as .... my_package.code.get_conn

And in this case you need to patch my_package.code.get_conn not the original package you imported get_conn from.

Once you realise this, patching becomes much easier.

Source https://stackoverflow.com/questions/69276878

Community Discussions contain sources that include Stack Exchange Network

Tutorials and Learning Resources in Mock

Tutorials and Learning Resources are not available at this moment for Mock

Share this Page

share link

Get latest updates on Mock