├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── runConfigurations.xml
└── vcs.xml
├── AS.PNG
├── CODE-OF-CONDUCT.md
├── CONTRIBUTING.md
├── PULL_REQUEST_TEMPLATE.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── anjan
│ │ └── mockitounittesttutorial
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── anjan
│ │ │ └── mockitounittesttutorial
│ │ │ ├── Cache.java
│ │ │ ├── EmailService.java
│ │ │ ├── InitialContext.java
│ │ │ ├── Locator.java
│ │ │ ├── LocatorService.java
│ │ │ ├── MainActivity.java
│ │ │ ├── MessagingService.java
│ │ │ ├── Point.java
│ │ │ ├── SMSService.java
│ │ │ ├── ServiceLocator.java
│ │ │ ├── Utils.java
│ │ │ ├── async
│ │ │ ├── DummyCallback.java
│ │ │ ├── DummyCaller.java
│ │ │ ├── DummyCollaborator.java
│ │ │ └── db
│ │ │ │ ├── CustomerDao.java
│ │ │ │ ├── EntityManager.java
│ │ │ │ └── Logger.java
│ │ │ ├── contributor
│ │ │ └── ContributorActivity.java
│ │ │ ├── exercise
│ │ │ ├── UpdateUsernameUseCaseSync.java
│ │ │ ├── description.txt
│ │ │ ├── eventbus
│ │ │ │ ├── EventBusPoster.java
│ │ │ │ └── UserDetailsChangedEvent.java
│ │ │ ├── networking
│ │ │ │ ├── NetworkErrorException.java
│ │ │ │ └── UpdateUsernameHttpEndpointSync.java
│ │ │ └── users
│ │ │ │ ├── User.java
│ │ │ │ └── UsersCache.java
│ │ │ ├── mock
│ │ │ ├── Customer.java
│ │ │ ├── EmailSender.java
│ │ │ ├── Event.java
│ │ │ ├── EventRecorder.java
│ │ │ ├── InvoiceStorage.java
│ │ │ └── LateInvoiceNotifier.java
│ │ │ ├── stub
│ │ │ ├── Customer.java
│ │ │ ├── CustomerReader.java
│ │ │ └── DbManager.java
│ │ │ └── sync
│ │ │ ├── LoginUseCaseSync.java
│ │ │ ├── authtoken
│ │ │ └── AuthTokenCache.java
│ │ │ ├── eventbus
│ │ │ ├── EventBusPoster.java
│ │ │ └── LoggedInEvent.java
│ │ │ └── networking
│ │ │ ├── LoginHttpEndpointSync.java
│ │ │ └── NetworkErrorException.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── anjan
│ └── mockitounittesttutorial
│ ├── LocatorTest.java
│ ├── async
│ ├── DummyCallerTest.java
│ └── db
│ │ └── CustomerDaoTest.java
│ ├── mock
│ └── LateInvoiceNotifierTest.java
│ ├── stub
│ └── CustomerReaderTest.java
│ └── sync
│ └── LoginUseCaseSyncTest.java
├── assets
└── Unit test Documentation.pdf
├── build.gradle
├── doc
├── FOSS MileStone 2.pptx
├── FOSS Milestone 1.pptx
└── Pull request and merge conflict with rebase.pdf
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── readme.md
├── settings.gradle
└── slides
├── Unit test-1.pptx
├── Unit test-2.pptx
└── Unit test-3.pptx
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
12 | ## Description
13 |
14 |
15 | ## Expected Behavior
16 |
17 |
18 | ## Actual Behavior
19 |
20 |
21 | ## Possible Fix
22 |
23 |
24 | ## Steps to Reproduce
25 |
26 |
27 | 1.
28 | 2.
29 | 3.
30 | 4.
31 |
32 | ## Context
33 |
34 |
35 | ## Your Environment
36 |
37 | * App version used:
38 | * Device Name and version:
39 | * Operating System and version:
40 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
12 | ## I'm submitting a ...
13 |
14 | - [ ] feature request
15 | - [ ] support request
16 |
17 | ## Expected Behavior
18 |
19 |
20 | ## Actual Behavior
21 |
22 |
23 |
24 | ## What is the motivation / use case for changing the behavior?
25 |
26 |
27 |
28 | ## Your Environment
29 |
30 | * App version used:
31 | * Device Name and version:
32 | * Operating System and version:
33 |
34 |
35 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 | *.aab
5 |
6 | # Files for the ART/Dalvik VM
7 | *.dex
8 |
9 | # Java class files
10 | *.class
11 |
12 | # Generated files
13 | bin/
14 | gen/
15 | out/
16 | release/
17 |
18 | # Gradle files
19 | .gradle/
20 | build/
21 |
22 | # Local configuration file (sdk path, etc)
23 | local.properties
24 |
25 | # Proguard folder generated by Eclipse
26 | proguard/
27 |
28 | # Log Files
29 | *.log
30 |
31 | # Android Studio Navigation editor temp files
32 | .navigation/
33 |
34 | # Android Studio captures folder
35 | captures/
36 |
37 | # IntelliJ
38 | *.iml
39 | .idea/workspace.xml
40 | .idea/tasks.xml
41 | .idea/gradle.xml
42 | .idea/assetWizardSettings.xml
43 | .idea/dictionaries
44 | .idea/libraries
45 | # Android Studio 3 in .gitignore file.
46 | .idea/caches
47 | .idea/modules.xml
48 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you
49 | .idea/navEditor.xml
50 |
51 | # Keystore files
52 | # Uncomment the following lines if you do not want to check your keystore files in.
53 | #*.jks
54 | #*.keystore
55 |
56 | # External native build folder generated in Android Studio 2.2 and later
57 | .externalNativeBuild
58 |
59 | # Google Services (e.g. APIs or Firebase)
60 | # google-services.json
61 |
62 | # Freeline
63 | freeline.py
64 | freeline/
65 | freeline_project_description.json
66 |
67 | # fastlane
68 | fastlane/report.xml
69 | fastlane/Preview.html
70 | fastlane/screenshots
71 | fastlane/test_output
72 | fastlane/readme.md
73 |
74 | # Version control
75 | vcs.xml
76 |
77 | # lint
78 | lint/intermediates/
79 | lint/generated/
80 | lint/outputs/
81 | lint/tmp/
82 | # lint/reports/
83 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/AS.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/AS.PNG
--------------------------------------------------------------------------------
/CODE-OF-CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies within all project spaces, and it also applies when
49 | an individual is representing the project or its community in public spaces.
50 | Examples of representing a project or community include using an official
51 | project e-mail address, posting via an official social media account, or acting
52 | as an appointed representative at an online or offline event. Representation of
53 | a project may be further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at [info@telemesh.net]. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 |
4 | # Table of contents
5 | 1. [Introduction](#introduction)
6 | 2. [Community Code of Conduct](#codeofconduct)
7 | 1. [Be considerate](#beconsiderate)
8 | 2. [Be respectful](#berespectful)
9 | 3. [Be collaborative](#becollaborative)
10 | 4. [When you disagree, consult others](#disagree)
11 | 5. [When you're unsure, ask for help](#unsure)
12 | 6. [Step down considerately](#stepdown)
13 |
14 | 3. [Your First Contribution](#firstcontribution)
15 | 4. [Support questions](#supportquestions)
16 | 5. [Reporting issues](#reportissue)
17 | 6. [Fix Bugs](#fixbugs)
18 | 7. [Implement Features](#features)
19 | 8. [Submitting an Issue](#submitissue)
20 | 9. [Feature requests](#featurereq)
21 | 10. [Code review process](#codereview)
22 | 11. [Community](#community)
23 | 12. [Pull Requests](#pullreq)
24 | 1. [How to create PR](#howpullreq)
25 | 13. [Git Commit Guidelines](#gitcommit)
26 | 14. [Coding style guide](#codingstyle)
27 | 15. [Organize github issues](#organize)
28 | 16. [Issue Referencing on Github](#issuereference)
29 |
30 |
31 |
32 | ## Introduction
33 |
34 | First off, thank you for considering contributing to MockTest. It's people like you that make MockTest such a great tool.
35 |
36 | When contributing to this repository, please first discuss the change you wish to make via issue ticket ([sample](https://github.com/anjandebnath/MockitoUnitTestTutorial/issues/5)) with the owners of this repository before making a change.
37 |
38 | Please note we have a code of conduct, please follow it in all your interactions with the project.
39 |
40 | When contributing to MockTest, we ask that you:
41 |
42 | - let us know what you plan in the [GitHub Issue tracker](https://github.com/anjandebnath/MockitoUnitTestTutorial/projects/2) so we can provide feedback.
43 |
44 | - provide tests and documentation whenever possible. It is very unlikely that we will accept new features or functionality into MockTest without the proper testing and documentation. When fixing a bug, provide a failing test case that your patch solves.
45 |
46 | - open a GitHub Pull Request with your patches and we will review your contribution and respond as quickly as possible. Keep in mind that this is an open source project, and it may take us some time to get back to you. Your patience is very much appreciated.
47 |
48 |
49 |
50 | ## Community Code of Conduct
51 |
52 |
53 | The goal is to maintain a MockTest community that's pleasant for everyone.
54 | That's why we would greatly appreciate it if everyone contributing to and
55 | interacting with the community also followed this Code of Conduct.
56 |
57 |
58 | ### Be considerate
59 |
60 |
61 | Your work will be used by other people, and you in turn will depend on the
62 | work of others. Any decision you take will affect users and colleagues, and
63 | we expect you to take those consequences into account when making decisions.
64 | Even if it's not obvious at the time, our contributions to MockTest will impact
65 | the work of others. For example, changes to code, infrastructure, policy,
66 | documentation and translations during a release may negatively impact
67 | others work.
68 |
69 | ### Be respectful
70 |
71 |
72 | The MockTest community and its members treat one another with respect. Everyone
73 | can make a valuable contribution to MockTest. We may not always agree, but
74 | disagreement is no excuse for poor behavior and poor manners. We might all
75 | experience some frustration now and then, but we cannot allow that frustration
76 | to turn into a personal attack. It's important to remember that a community
77 | where people feel uncomfortable or threatened isn't a productive one. We
78 | expect members of the MockTest community to be respectful when dealing with
79 | other contributors as well as with people outside the MockTest project and with
80 | users of MockTest.
81 |
82 | ### Be collaborative
83 |
84 |
85 | Collaboration is central to MockTest and to the larger free software community.
86 | We should always be open to collaboration. Your work should be done
87 | transparently and patches from MockTest should be given back to the community
88 | when they're made, not just when the distribution releases. If you wish
89 | to work on new code for existing upstream projects, at least keep those
90 | projects informed of your ideas and progress. It many not be possible to
91 | get consensus from upstream, or even from your colleagues about the correct
92 | implementation for an idea, so don't feel obliged to have that agreement
93 | before you begin, but at least keep the outside world informed of your work,
94 | and publish your work in a way that allows outsiders to test, discuss, and
95 | contribute to your efforts.
96 |
97 | ### When you disagree, consult others
98 |
99 |
100 | Disagreements, both political and technical, happen all the time and
101 | the MockTest community is no exception. It's important that we resolve
102 | disagreements and differing views constructively and with the help of the
103 | community and community process. If you really want to go a different
104 | way, then we encourage you to make a derivative distribution or alternate
105 | set of packages that still build on the work we've done to utilize as common
106 | of a core as possible.
107 |
108 | ### When you're unsure, ask for help
109 |
110 |
111 | Nobody knows everything, and nobody is expected to be perfect. Asking
112 | questions avoids many problems down the road, and so questions are
113 | encouraged. Those who are asked questions should be responsive and helpful.
114 | However, when asking a question, care must be taken to do so in an appropriate
115 | forum.
116 |
117 | ### Step down considerately
118 |
119 | Developers on every project come and go and MockTest is no different. When you
120 | leave or disengage from the project, in whole or in part, we ask that you do
121 | so in a way that minimizes disruption to the project. This means you should
122 | tell people you're leaving and take the proper steps to ensure that others
123 | can pick up where you leave off.
124 |
125 |
126 | ## Your First Contribution
127 |
128 | Unsure where to begin contributing to MockTest? You can start by looking through these `good-first` and `help-wanted` issues:
129 |
130 | * [Good first issues](https://github.com/anjandebnath/MockitoUnitTestTutorial/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) - issues which should only require a few lines of code, and a test or two.
131 | * [Help wanted issues](https://github.com/anjandebnath/MockitoUnitTestTutorial/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) - issues which should be a bit more involved than `good-first` issues.
132 |
133 | Both issue lists are sorted by total number of comments. While not perfect, number of comments is a reasonable proxy for impact a given change will have.
134 |
135 | Working on your first Pull Request? You can learn how from this *free* series, [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github).
136 |
137 | At this point, you're ready to make your changes! Feel free to ask for help; everyone is a beginner at first :smile_cat:
138 |
139 | If a maintainer asks you to "rebase" your PR, they're saying that a lot of code has changed, and that you need to update your branch so it's easier to merge.
140 |
141 |
142 | ## Support questions
143 |
144 |
145 | Please, don't use the issue tracker for this. Use one of the following
146 | resources for questions about your own code:
147 |
148 | * The ``#get-help`` channel on our [Discord chat](comming soon)
149 |
150 | * The mailing list media@MockTest.net for long term discussion or larger issues.
151 |
152 |
153 | ## Reporting issues
154 |
155 | Report bugs at https://github.com/anjandebnath/MockitoUnitTestTutorial/issues.
156 |
157 | We have different templates for bug report and feature request which you can find during issue creation.
158 |
159 | ```text
160 |
161 |
162 |
163 | ### Description
164 |
165 |
166 | ### Expected Behavior
167 |
168 |
169 | ### Actual Behavior
170 |
171 |
172 | ### Possible Fix
173 |
174 |
175 | ### Steps to Reproduce
176 |
177 |
178 | 1.
179 | 2.
180 | 3.
181 | 4.
182 |
183 | ### Context
184 |
185 |
186 | ### Your Environment
187 |
188 | * App version used:
189 | * Device Name and version:
190 | * Operating System and version:
191 |
192 | ```
193 |
194 |
195 | ## Fix Bugs
196 |
197 | Look through the GitHub issues for bugs. Anything tagged with "bug"
198 | is open to whoever wants to implement it.
199 | [Sample issue](https://github.com/anjandebnath/MockitoUnitTestTutorial/issues/5)
200 |
201 |
202 | ## Implement Features
203 |
204 |
205 | Look through the GitHub issues for features. Anything tagged with "enhancement"
206 | and "optimization" is open to whoever wants to implement it.
207 |
208 | Please do not combine multiple feature enhancements into a single pull request.
209 |
210 | Note: We're trying to keep the code base
211 | small, extensible, and streamlined. Whenever possible, it's best to try and
212 | implement feature ideas as separate projects outside of the core codebase.
213 |
214 |
215 |
216 | ## Submitting an Issue
217 |
218 | Before you submit an issue,
219 | **search** the issues archive;
220 | maybe the issue has already been submitted or considered. If the issue appears to be a bug,
221 | and hasn't been reported, open a [new issue](https://github.com/anjandebnath/MockitoUnitTestTutorial/issues/new/choose).
222 |
223 | > Please **do not report duplicate issues**; help us maximize the effort we can spend fixing
224 | issues and adding enhancements.
225 |
226 | Providing the following information will increase the chances of your issue being dealt with
227 | quickly:
228 |
229 | * **Issue Title** - provide a concise issue title prefixed with a snake-case name of the
230 | associated service or component (if any): `: `.
231 | Adding the `md-` prefix should be avoided.
232 |
233 | > e.g.
234 | > * unit-test: mockito library syncing problem [#5](https://github.com/anjandebnath/MockitoUnitTestTutorial/issues/5)
235 |
236 |
237 | * **Complete the full Issue Template** - You will get the issue template where we put some predefined rules to create an issue.
238 | Moreover we are always open to make any changes according contributor's feedback.
239 |
240 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
241 | causing the problem (line of code or commit).
242 |
243 | #### Submitting Pull Requests
244 |
245 | **Important**: We are not accepting major feature requests or PRs that contain major new features
246 | or breaking changes at this time but we are welcoming to plan it for future or, we can discuss further offline.
247 |
248 |
249 | ## Feature requests
250 |
251 | If you find yourself wishing for a feature that doesn't exist in MockTest, you are probably not alone. There are bound to be others out there with similar needs. Many of the features that MockTest has today have been added because our users saw the need. Open an issue on our issues list on GitHub which describes the feature you would like to see, why you need it, and how it should work.
252 |
253 | ## Code review process
254 |
255 | The core team looks at Pull Requests on a regular basis.Each code review should aim to achieve one or more of these goals; however, not all code reviews need to aim for all goals.
256 |
257 | Code review goals:
258 |
259 | - Finding bugs
260 | - Bugs found in code review require much less effort to find & fix than bugs found in QA/testing.
261 | - Coding style. Ensure that [Android coding standard](https://github.com/ustwo/android-coding-standards) and [Coding Pattern](https://blog.mindorks.com/android-code-style-and-guidelines-d5f80453d5c7) are followed.
262 | - Improving code quality
263 | - Teaching best practices
264 | - Code consistency (can't tell the author from the code)
265 | - Learning code
266 | - Efficiency (getting pull requests reviewed quickly)
267 | - Ensuring that the pull request guidelines are followed.
268 |
269 |
270 | Code review processes:
271 |
272 | - Issue a pull request with a full link to your ticket in the description.
273 | - Click the "Request Review" option on the ticket to move into the "Code Review (pre commit)" state.
274 | - Add a comment linking to your pull request by its url.
275 |
276 | Code review checklists :
277 |
278 | - Variable naming convention.
279 | - Method naming convention.
280 | - is the Class file is written in suitable package that is defined in guideline.
281 | - Override methods should be listed upper and then the private methods.
282 | - xml naming convention.
283 | - Layout design.
284 | - Unit test check.
285 | - Proper commenting on each method.
286 | - Method body and if any logical improvement is needed.
287 | - If any 3rd party library used then is it good to use or not
288 | - No sophisticated url access/data on git commit
289 |
290 | ## Community
291 |
292 | We will finalise our contributors community and list down their details soon
293 |
294 | ## Pull Requests
295 |
296 | Follow all instructions in [the template](https://github.com/anjandebnath/MockitoUnitTestTutorial/blob/master/PULL_REQUEST_TEMPLATE.md)
297 | The process described here has several goals:
298 |
299 | - Maintain MockTest's code quality
300 | - Fix problems that are important to users
301 | - Engage the community in working toward the best possible MockTest
302 | - Enable a sustainable system for MockTest's maintainers to review contributions
303 |
304 | ### How to create PR
305 |
306 | [How to create PR on Github](https://www.digitalocean.com/community/tutorials/how-to-create-a-pull-request-on-github)
307 |
308 | [How to update existing PR](https://www.digitalocean.com/community/tutorials/how-to-rebase-and-update-a-pull-request)
309 |
310 |
311 | ## Git Commit Guidelines
312 |
313 | We have very precise rules over how our git commit messages can be formatted. This leads to **more
314 | readable messages** that are easy to follow when looking through the **project history**.
315 |
316 |
317 | ### Commit Message Format
318 | Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
319 | format that includes a **type**, a **scope** and a **subject**:
320 |
321 | ```html
322 | ():
323 |
324 |
325 |
326 |
327 | ```
328 |
329 | > Any line of the commit message cannot be longer 100 characters!
330 | This allows the message to be easier to read on GitHub as well as in various Git tools.
331 |
332 | ##### Type
333 | Must be one of the following:
334 |
335 | * **feat**: A new feature
336 | * **fix**: A bug fix
337 | * **docs**: Documentation only changes
338 | * **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
339 | semi-colons, etc)
340 | * **refactor**: A code change that neither fixes a bug nor adds a feature
341 | * **perf**: A code change that improves performance
342 | * **test**: Adding missing tests
343 | * **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
344 | generation
345 |
346 | ##### Scope
347 | The scope could be anything that helps specifying the scope (or feature) that is changing.
348 |
349 | Examples
350 | - select(multiple):
351 | - dialog(alert):
352 |
353 | ##### Subject
354 | The subject contains a succinct description of the change:
355 |
356 | * use the imperative, present tense: "change" not "changed" nor "changes"
357 | * don't capitalize first letter
358 | * no dot (.) at the end
359 |
360 | ##### Body
361 | Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes"
362 | The body should include the motivation for the change and contrast this with previous behavior.
363 |
364 | ##### Footer
365 | The footer should contain any information about **Breaking Changes** and is also the place to
366 | reference GitHub issues that this commit **Closes**, **Fixes**, or **Relates to**.
367 |
368 | > Breaking Changes are intended to be highlighted in the ChangeLog as changes that will require
369 | community users to modify their code after updating to a version that contains this commit.
370 |
371 | ##### Sample Commit messages:
372 | ```text
373 | fix(autocomplete): don't show the menu panel when readonly
374 |
375 | this could sometimes happen when no value was selected
376 |
377 | Fixes #11231
378 | ```
379 | ```text
380 | feat(chips): trigger ng-change on chip addition/removal
381 |
382 | * add test of `ng-change` for `md-chips`
383 | * add docs regarding `ng-change` for `md-chips` and `md-contact-chips`
384 | * add demo for ng-change on `md-chips`
385 | * add demo for ng-change on `md-contact-chips`
386 |
387 | Fixes #11161 Fixes #3857
388 | ```
389 |
390 | ```text
391 | refactor(content): prefix mdContent scroll- attributes
392 |
393 | BREAKING CHANGE: md-content's `scroll-` attributes are now prefixed with `md-`.
394 |
395 | Change your code from this:
396 |
397 | ```html
398 |
399 | ```
400 |
401 | To this:
402 |
403 | ```html
404 |
405 | ```
406 | ```
407 |
408 | ## Coding style guide
409 |
410 | We are following this [Android coding standard](https://github.com/ustwo/android-coding-standards) and [Coding Pattern](https://blog.mindorks.com/android-code-style-and-guidelines-d5f80453d5c7)
411 | for our coding.
412 |
413 |
414 | ## Organize github issues
415 |
416 | We are following this guideline [Style Guide](https://robinpowered.com/blog/best-practice-system-for-organizing-and-tagging-github-issues/)
417 |
418 | ## Issue Referencing on Github
419 |
420 | You can include keywords in your pull request descriptions, as well as commit messages, to automatically close issues in GitHub.
421 | [About issue reference](https://help.github.com/en/articles/closing-issues-using-keywords#about-issue-references)
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Description
2 |
3 | Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
4 |
5 | Fixes # (issue)
6 |
7 | ## Type of change
8 |
9 | Please delete options that are not relevant.
10 |
11 | - [ ] Bug fix (non-breaking change which fixes an issue)
12 | - [ ] New feature (non-breaking change which adds functionality)
13 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
14 | - [ ] This change requires a documentation update
15 |
16 | ## How Has This Been Tested?
17 |
18 | Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
19 |
20 | - [ ] Test A
21 | - [ ] Test B
22 |
23 | **Test Configuration**:
24 | * Firmware version:
25 | * Hardware:
26 | * Toolchain:
27 | * SDK:
28 |
29 | ## Checklist:
30 |
31 | - [ ] My code follows the style guidelines of this project
32 | - [ ] I have performed a self-review of my own code
33 | - [ ] I have commented my code, particularly in hard-to-understand areas
34 | - [ ] I have made corresponding changes to the documentation
35 | - [ ] My changes generate no new warnings
36 | - [ ] I have added tests that prove my fix is effective or that my feature works
37 | - [ ] New and existing unit tests pass locally with my changes
38 | - [ ] Any dependent changes have been merged and published in downstream modules
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | defaultConfig {
6 | applicationId "com.anjan.mockitounittesttutorial"
7 | minSdkVersion 15
8 | targetSdkVersion 27
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | compileOptions {
20 | sourceCompatibility JavaVersion.VERSION_1_8
21 | targetCompatibility JavaVersion.VERSION_1_8
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(include: ['*.jar'], dir: 'libs')
27 | implementation 'com.android.support:appcompat-v7:27.1.1'
28 | implementation 'com.android.support.constraint:constraint-layout:1.1.0'
29 | testImplementation 'junit:junit:4.12'
30 | // required if you want to use Mockito for unit tests
31 | testImplementation 'org.mockito:mockito-core:2.7.22'
32 | // required if you want to use Mockito for Android tests
33 | androidTestImplementation 'org.mockito:mockito-android:2.7.22'
34 | // required if you want to use Hamcrest matching
35 | testImplementation 'org.hamcrest:hamcrest-library:1.3'
36 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
37 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
38 | }
39 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/anjan/mockitounittesttutorial/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.anjan.mockitounittesttutorial", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/Cache.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class Cache {
7 |
8 | private List services = new ArrayList<>();
9 |
10 | public MessagingService getService(String serviceName) {
11 | // retrieve from the list
12 | return new EmailService();
13 | }
14 |
15 | public void addService(MessagingService newService) {
16 | // add to the list
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/EmailService.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | public class EmailService implements MessagingService {
4 |
5 | public String getMessageBody() {
6 | return "email message";
7 | }
8 |
9 | public String getServiceName() {
10 | return "EmailService";
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/InitialContext.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | public class InitialContext {
4 |
5 | public Object lookup(String serviceName) {
6 | if (serviceName.equalsIgnoreCase("EmailService")) {
7 | return new EmailService();
8 | } else if (serviceName.equalsIgnoreCase("SMSService")) {
9 | return new SMSService();
10 | }
11 | return null;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/Locator.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 |
4 | import android.util.Log;
5 |
6 | /**
7 | * Created by Anjan Debnath on 5/22/2018.
8 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
9 | */
10 | public class Locator {
11 | private final LocatorService locatorService;
12 |
13 | private static Cache cache = new Cache();
14 |
15 | public Locator(LocatorService locatorService) {
16 | this.locatorService = locatorService;
17 | }
18 |
19 | public Point locate(int x, int y) {
20 | if (x < 0 || y < 0) {
21 | return new Point(Math.abs(x), Math.abs(y));
22 | } else {
23 | return locatorService.geoLocate(new Point(x, y));
24 | }
25 | }
26 |
27 |
28 | public static MessagingService getService(String serviceName) {
29 |
30 |
31 | MessagingService service = cache.getService(serviceName);
32 |
33 | if (service != null) {
34 | return service;
35 | }
36 |
37 | InitialContext context = new InitialContext();
38 | MessagingService service1 = (MessagingService) context
39 | .lookup(serviceName);
40 | cache.addService(service1);
41 | return service1;
42 | }
43 |
44 | private void LocationTracker(Point point){
45 |
46 | MessagingService service
47 | = ServiceLocator.getService("EmailService");
48 | String email = service.getMessageBody();
49 |
50 | MessagingService smsService
51 | = ServiceLocator.getService("SMSService");
52 | String sms = smsService.getMessageBody();
53 | }
54 |
55 | private void fixIssueFive(){
56 | Log.e("TAG", "Fix the issue no 5");
57 |
58 | if(locatorService!= null){
59 | Point p = new Point(22, 34);
60 | locatorService.geoLocate(p);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/LocatorService.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | /**
4 | * Created by Anjan Debnath on 5/22/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public class LocatorService {
8 | public Point geoLocate(Point point) {
9 | return new Point(point.getX(), point.getY());
10 | }
11 |
12 | public Point generatePointWithinDistance(Point point, int distance) {
13 | return new Point(point.getX() + Utils.randomDistance(distance), point.getY() + Utils.randomDistance(distance));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 |
6 | public class MainActivity extends AppCompatActivity {
7 |
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | setContentView(R.layout.activity_main);
12 | }
13 |
14 | /**
15 | * Gets the unique id.
16 | *
17 | * @return the unique id
18 | */
19 | public int getUniqueId() {
20 | return 43;
21 | }
22 |
23 | public int testing(int num) {
24 | someMethod("");
25 | return num;
26 | }
27 |
28 | public void someMethod(String someMethod) {
29 | testing(1);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/MessagingService.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | public interface MessagingService {
4 | String getMessageBody();
5 | String getServiceName();
6 | }
7 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/Point.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | /**
4 | * Created by Anjan Debnath on 5/22/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public class Point {
8 | private int x;
9 | private int y;
10 |
11 | public Point(int x, int y) {
12 | this.x = x;
13 | this.y = y;
14 | }
15 |
16 | public int getX() {
17 | return x;
18 | }
19 |
20 | public int getY() {
21 | return y;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/SMSService.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | public class SMSService implements MessagingService {
4 |
5 | public String getMessageBody() {
6 | return "sms message";
7 | }
8 |
9 | public String getServiceName() {
10 | return "SMSService";
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/ServiceLocator.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | public class ServiceLocator {
4 |
5 | private static Cache cache = new Cache();
6 |
7 | public static MessagingService getService(String serviceName) {
8 |
9 | MessagingService service = cache.getService(serviceName);
10 |
11 | if (service != null) {
12 | return service;
13 | }
14 |
15 | InitialContext context = new InitialContext();
16 | MessagingService service1 = (MessagingService) context
17 | .lookup(serviceName);
18 | cache.addService(service1);
19 | return service1;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/Utils.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * Created by Anjan Debnath on 5/22/2018.
7 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
8 | */
9 | public class Utils {
10 | private static final Random RAND = new Random();
11 |
12 | private Utils() {
13 | // Utilities class
14 | }
15 |
16 | public static int randomDistance(int distance) {
17 | return RAND.nextInt(distance + distance) - distance;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/async/DummyCallback.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.async;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by Anjan Debnath on 7/23/2018.
7 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
8 | */
9 | public interface DummyCallback {
10 | public void onSuccess(List result);
11 | public void onFail(int code);
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/async/DummyCaller.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.async;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Created by Anjan Debnath on 7/23/2018.
8 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
9 | */
10 | public class DummyCaller implements DummyCallback{
11 |
12 | DummyCollaborator dummyCollaborator;
13 |
14 | private List result = new ArrayList();
15 |
16 | public DummyCaller(DummyCollaborator dummyCollaborator){
17 | this.dummyCollaborator = dummyCollaborator;
18 | }
19 |
20 | public void doSomethingAsynchronously(){
21 | dummyCollaborator.doSomethingAsynchronously(this);
22 | }
23 |
24 | public List getResult(){
25 | return this.result;
26 | }
27 |
28 | @Override
29 | public void onSuccess(List result) {
30 | this.result = result;
31 | System.out.println("On success");
32 | }
33 |
34 | @Override
35 | public void onFail(int code) {
36 | System.out.println("On Fail");
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/async/DummyCollaborator.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.async;
2 |
3 | import java.util.Collections;
4 |
5 | /**
6 | * Created by Anjan Debnath on 7/23/2018.
7 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
8 | */
9 | public class DummyCollaborator {
10 | public static int ERROR_CODE = 1;
11 |
12 | public DummyCollaborator() {
13 |
14 | }
15 |
16 | public void doSomethingAsynchronously(final DummyCallback callback){
17 | new Thread(new Runnable() {
18 | @Override
19 | public void run() {
20 |
21 | try {
22 | Thread.sleep(5000);
23 | callback.onSuccess(Collections.EMPTY_LIST);
24 | } catch (InterruptedException e) {
25 | callback.onFail(ERROR_CODE);
26 | e.printStackTrace();
27 | }
28 | }
29 | }).start();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/async/db/CustomerDao.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.async.db;
2 |
3 | import com.anjan.mockitounittesttutorial.mock.Customer;
4 |
5 | /**
6 | * Created by Anjan Debnath on 8/6/2018.
7 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
8 | */
9 | public class CustomerDao {
10 |
11 | private EntityManager entityManager;
12 |
13 | private Logger logger;
14 |
15 | public CustomerDao(EntityManager entityManager, Logger logger){
16 | this.entityManager = entityManager;
17 | this.logger = logger;
18 | }
19 |
20 | /**
21 | * once the customer is saved using the persist method, its database ID is sent to the logger.
22 | * For this contrived example, the code will work just fine in the real system, as the database
23 | * will indeed assign an ID to the object as soon as it is saved.
24 | * But how can we replicate this processing in our unit test?
25 | * The persist method does not return an argument so we cannot mock it with the usual when/then directives.
26 | * However, even for this corner case, Mockito still has a solution:
27 | * @param firstName
28 | * @param lastName
29 | */
30 | public void saveCustomer(String firstName, String lastName) {
31 | if(firstName == null || lastName==null)
32 | {
33 | logger.error("Missing customer information");
34 | throw new IllegalArgumentException();
35 | }
36 | Customer customer = new Customer(firstName,lastName);
37 | entityManager.persist(customer);
38 | entityManager.flush();
39 | logger.info("Saved customer with id {}", customer.getId());
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/async/db/EntityManager.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.async.db;
2 |
3 | import com.anjan.mockitounittesttutorial.mock.Customer; /**
4 | * Created by Anjan Debnath on 8/6/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public class EntityManager {
8 |
9 | public void persist(Customer customer) {
10 | }
11 |
12 | public void flush() {
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/async/db/Logger.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.async.db;
2 |
3 | /**
4 | * Created by Anjan Debnath on 8/6/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public class Logger {
8 |
9 |
10 | public void info(String s, long id) {
11 |
12 | }
13 |
14 | public void error(String missing_customer_information) {
15 |
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/contributor/ContributorActivity.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.contributor;
2 |
3 |
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.util.Log;
8 |
9 | import com.anjan.mockitounittesttutorial.R;
10 |
11 | public class ContributorActivity extends AppCompatActivity {
12 |
13 | @Override
14 | public void onCreate(@Nullable Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_main);
17 | }
18 |
19 | @Override
20 | protected void onResume() {
21 | super.onResume();
22 | }
23 |
24 | @Override
25 | protected void onPause() {
26 | super.onPause();
27 | }
28 |
29 |
30 | public void methodCreatedByOwner() {
31 |
32 | Log.d("Owner", "This method has created by owner");
33 | }
34 | public void methodCreatedByContributor(){
35 |
36 | Log.d("Owner", "This method has created by contributor machine");
37 |
38 | Log.d("Pull request", "change log test");
39 |
40 | }
41 | }
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/exercise/UpdateUsernameUseCaseSync.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.exercise;
2 |
3 |
4 | import com.anjan.mockitounittesttutorial.exercise.eventbus.EventBusPoster;
5 | import com.anjan.mockitounittesttutorial.exercise.eventbus.UserDetailsChangedEvent;
6 | import com.anjan.mockitounittesttutorial.exercise.networking.NetworkErrorException;
7 | import com.anjan.mockitounittesttutorial.exercise.networking.UpdateUsernameHttpEndpointSync;
8 | import com.anjan.mockitounittesttutorial.exercise.users.User;
9 | import com.anjan.mockitounittesttutorial.exercise.users.UsersCache;
10 |
11 | public class UpdateUsernameUseCaseSync {
12 |
13 | public enum UseCaseResult {
14 | SUCCESS,
15 | FAILURE,
16 | NETWORK_ERROR
17 | }
18 |
19 | private final UpdateUsernameHttpEndpointSync mUpdateUsernameHttpEndpointSync;
20 | private final UsersCache mUsersCache;
21 | private final EventBusPoster mEventBusPoster;
22 |
23 | public UpdateUsernameUseCaseSync(UpdateUsernameHttpEndpointSync updateUsernameHttpEndpointSync,
24 | UsersCache usersCache,
25 | EventBusPoster eventBusPoster) {
26 | mUpdateUsernameHttpEndpointSync = updateUsernameHttpEndpointSync;
27 | mUsersCache = usersCache;
28 | mEventBusPoster = eventBusPoster;
29 | }
30 |
31 | public UseCaseResult updateUsernameSync(String userId, String username) {
32 | UpdateUsernameHttpEndpointSync.EndpointResult endpointResult = null;
33 | try {
34 | endpointResult = mUpdateUsernameHttpEndpointSync.updateUsername(userId, username);
35 | } catch (NetworkErrorException e) {
36 | // the bug here is "swallowed" exception instead of return
37 | }
38 |
39 | if (isSuccessfulEndpointResult(endpointResult)) {
40 | // the bug here is reversed arguments
41 | User user = new User(endpointResult.getUsername(), endpointResult.getUserId());
42 | mEventBusPoster.postEvent(new UserDetailsChangedEvent(new User(userId, username)));
43 | mUsersCache.cacheUser(user);
44 | return UseCaseResult.SUCCESS;
45 | } else {
46 | return UseCaseResult.FAILURE;
47 | }
48 | }
49 |
50 | private boolean isSuccessfulEndpointResult(UpdateUsernameHttpEndpointSync.EndpointResult endpointResult) {
51 | // the bug here is the wrong definition of successful response
52 | return endpointResult.getStatus() == UpdateUsernameHttpEndpointSync.EndpointResultStatus.SUCCESS
53 | || endpointResult.getStatus() == UpdateUsernameHttpEndpointSync.EndpointResultStatus.GENERAL_ERROR;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/exercise/description.txt:
--------------------------------------------------------------------------------
1 | Description:
2 | Your goal is to find all bugs in UpdateUsernameUseCaseSync class without looking at its internal
3 | implementation.
4 | You should:
5 | 1) Open the test class and set up system under test (SUT).
6 | 2) Implement the required test doubles with Mockito.
7 | 3) Think about the required test cases and list them as comments.
8 | 4) Write actual tests and identify which requirements aren't satisfied.
9 | 5) Read tests output and try to come up with a hypothesis about the production code.
10 | 6) Fix the production code.
11 | 7) Make sure that all tests pass.
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/exercise/eventbus/EventBusPoster.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.exercise.eventbus;
2 |
3 | public interface EventBusPoster {
4 |
5 | void postEvent(Object event);
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/exercise/eventbus/UserDetailsChangedEvent.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.exercise.eventbus;
2 |
3 | import com.anjan.mockitounittesttutorial.exercise.users.User;
4 |
5 |
6 | public class UserDetailsChangedEvent {
7 |
8 | private final User mUser;
9 |
10 | public UserDetailsChangedEvent(User user) {
11 | mUser = user;
12 | }
13 |
14 |
15 |
16 | public User getUser() {
17 | return mUser;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/exercise/networking/NetworkErrorException.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.exercise.networking;
2 |
3 | public class NetworkErrorException extends Exception {
4 | }
5 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/exercise/networking/UpdateUsernameHttpEndpointSync.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.exercise.networking;
2 |
3 | public interface UpdateUsernameHttpEndpointSync {
4 |
5 | /**
6 | * Update user's username on the server
7 | * @return the aggregated result
8 | * @throws NetworkErrorException if operation failed due to network error
9 | */
10 | EndpointResult updateUsername(String userId, String username) throws NetworkErrorException;
11 |
12 | enum EndpointResultStatus {
13 | SUCCESS,
14 | AUTH_ERROR,
15 | SERVER_ERROR,
16 | GENERAL_ERROR
17 | }
18 |
19 | class EndpointResult {
20 | private final EndpointResultStatus mStatus;
21 | private final String mUserId;
22 | private final String mUsername;
23 |
24 | public EndpointResult(EndpointResultStatus status, String userId, String username) {
25 | mStatus = status;
26 | mUserId = userId;
27 | mUsername = username;
28 | }
29 |
30 | public EndpointResultStatus getStatus() {
31 | return mStatus;
32 | }
33 |
34 | public String getUserId() {
35 | return mUserId;
36 | }
37 |
38 | public String getUsername() {
39 | return mUserId;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/exercise/users/User.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.exercise.users;
2 |
3 | public class User {
4 | private final String mUserId;
5 | private final String mUsername;
6 |
7 | public User(String userId, String username) {
8 | mUserId = userId;
9 | mUsername = username;
10 | }
11 |
12 | public String getUserId() {
13 | return mUserId;
14 | }
15 |
16 | public String getUsername() {
17 | return mUsername;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/exercise/users/UsersCache.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.exercise.users;
2 |
3 | public interface UsersCache {
4 |
5 | void cacheUser(User user);
6 |
7 | User getUser(String userId);
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/mock/Customer.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.mock;
2 |
3 | /**
4 | * Created by Anjan Debnath on 7/25/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public class Customer {
8 |
9 | private long id;
10 |
11 | private String firstName;
12 |
13 | private String lastName;
14 |
15 | public Customer(String firstName, String lastName) {
16 | this.firstName = firstName;
17 | this.lastName = lastName;
18 | }
19 |
20 | public long getId() {
21 | return id;
22 | }
23 |
24 | public void setId(long id) {
25 | this.id = id;
26 | }
27 |
28 | public String getFirstName() {
29 | return firstName;
30 | }
31 |
32 | public void setFirstName(String firstName) {
33 | this.firstName = firstName;
34 | }
35 |
36 | public String getLastName() {
37 | return lastName;
38 | }
39 |
40 | public void setLastName(String lastName) {
41 | this.lastName = lastName;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/mock/EmailSender.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.mock;
2 |
3 | /**
4 | * Created by Anjan Debnath on 7/25/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public class EmailSender {
8 |
9 | public void sendEmail(Customer customer){
10 |
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/mock/Event.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.mock;
2 |
3 | import java.time.LocalDate;
4 |
5 | /**
6 | * Created by Anjan Debnath on 7/25/2018.
7 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
8 | */
9 | public class Event {
10 |
11 | public enum Type {REMINDER_SENT, REGISTRATION, INVOICE_ISSUED,PAYMENT, SETTLEMENT};
12 |
13 | public Type getType() {
14 | return type;
15 | }
16 |
17 | public void setType(Type type) {
18 | this.type = type;
19 | }
20 |
21 | public String getCustomerName() {
22 | return customerName;
23 | }
24 |
25 | public void setCustomerName(String customerName) {
26 | this.customerName = customerName;
27 | }
28 |
29 | public LocalDate getTimestamp() {
30 | return timestamp;
31 | }
32 |
33 | public void setTimestamp(LocalDate timestamp) {
34 | this.timestamp = timestamp;
35 | }
36 |
37 | private Type type;
38 | private String customerName;
39 | private LocalDate timestamp;
40 |
41 | Event(Type type, String customerName, LocalDate timestamp){
42 | this.type = type;
43 | this.customerName = customerName;
44 | this.timestamp = timestamp;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/mock/EventRecorder.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.mock;
2 |
3 | /**
4 | * Created by Anjan Debnath on 7/25/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public class EventRecorder {
8 |
9 |
10 | public void recordEvent(Event event){
11 | /**
12 | * record event
13 | */
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/mock/InvoiceStorage.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.mock;
2 |
3 | /**
4 | * Created by Anjan Debnath on 7/25/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public class InvoiceStorage {
8 |
9 | public boolean hasOutstandingInvoice(Customer customer){
10 | return true;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/mock/LateInvoiceNotifier.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.mock;
2 |
3 | import android.annotation.SuppressLint;
4 |
5 | import java.time.LocalDate;
6 |
7 | /**
8 | * Created by Anjan Debnath on 7/25/2018.
9 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
10 | */
11 | public class LateInvoiceNotifier {
12 |
13 | private final EmailSender emailSender;
14 | private final InvoiceStorage invoiceStorage;
15 | private final EventRecorder eventRecorder;
16 |
17 | private static final String NAME = "Susan Ivanova";
18 |
19 |
20 | public LateInvoiceNotifier(final EmailSender emailSender, final InvoiceStorage invoiceStorage, EventRecorder eventRecorder){
21 | this.emailSender = emailSender;
22 | this.invoiceStorage = invoiceStorage;
23 | this.eventRecorder = eventRecorder;
24 | }
25 |
26 | @SuppressLint("NewApi")
27 | public void notifyLate(Customer customer){
28 | if(invoiceStorage.hasOutstandingInvoice(customer)){
29 | eventRecorder.recordEvent(new Event(Event.Type.REMINDER_SENT, NAME, LocalDate.now()));
30 | emailSender.sendEmail(customer);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/stub/Customer.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.stub;
2 |
3 | /**
4 | * Created by Anjan Debnath on 7/25/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 |
8 | public class Customer {
9 |
10 | /**
11 | * DataStructure
12 | * Expose data
13 | * No behaviour
14 | * Can be instantiated with other Objects
15 | * No need to be substituted with test doubles
16 | */
17 |
18 | private long id;
19 |
20 | private String firstName;
21 |
22 | private String lastName;
23 |
24 | public long getId() {
25 | return id;
26 | }
27 |
28 | public void setId(long id) {
29 | this.id = id;
30 | }
31 |
32 | public String getFirstName() {
33 | return firstName;
34 | }
35 |
36 | public void setFirstName(String firstName) {
37 | this.firstName = firstName;
38 | }
39 |
40 | public String getLastName() {
41 | return lastName;
42 | }
43 |
44 | public void setLastName(String lastName) {
45 | this.lastName = lastName;
46 | }
47 |
48 |
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/stub/CustomerReader.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.stub;
2 |
3 | /**
4 | * Created by Anjan Debnath on 7/25/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 |
8 | public class CustomerReader {
9 |
10 | private DbManager mDbManager;
11 |
12 | public CustomerReader(DbManager dbManager) {
13 | this.mDbManager = dbManager;
14 | }
15 |
16 | public String findName(Long customerID){
17 | Customer customer = mDbManager.findCustomer(customerID);
18 | return customer.getFirstName() +" "+customer.getLastName();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/stub/DbManager.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.stub;
2 |
3 | /**
4 | * Created by Anjan Debnath on 7/25/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 |
8 | public class DbManager {
9 |
10 | public static final String FIRST_NAME = "Customer";
11 | public static final String LAST_NAME = "Name";
12 |
13 | /**
14 | * Object
15 | * Expose behaviours
16 | * Hide internal implementation detail
17 | * Should be injected into other Objects
18 | * Need to be unit tested explicitly
19 | * Eligible to be substituted with test doubles
20 | */
21 |
22 | public Customer findCustomer(Long customerId){
23 | Customer customer = null;
24 | if(customerId > 0){
25 | customer = new Customer();
26 | /**
27 | * here will be the database fetch code
28 | * and from that fetched value we will get the
29 | * customer.
30 | */
31 | customer.setId(customerId);
32 | customer.setFirstName(FIRST_NAME);
33 | customer.setLastName(LAST_NAME);
34 | }
35 | return customer;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/sync/LoginUseCaseSync.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.sync;
2 |
3 |
4 | import com.anjan.mockitounittesttutorial.sync.authtoken.AuthTokenCache;
5 | import com.anjan.mockitounittesttutorial.sync.eventbus.EventBusPoster;
6 | import com.anjan.mockitounittesttutorial.sync.eventbus.LoggedInEvent;
7 | import com.anjan.mockitounittesttutorial.sync.networking.LoginHttpEndpointSync;
8 | import com.anjan.mockitounittesttutorial.sync.networking.NetworkErrorException;
9 |
10 | /**
11 | * Created by Anjan Debnath on 7/23/2018.
12 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
13 | */
14 |
15 | public class LoginUseCaseSync {
16 |
17 | public enum UseCaseResult {
18 | SUCCESS,
19 | FAILURE,
20 | NETWORK_ERROR
21 | }
22 |
23 | /**
24 | * Collaborators
25 | */
26 | private final LoginHttpEndpointSync mLoginHttpEndpointSync;
27 | private final AuthTokenCache mAuthTokenCache;
28 | private final EventBusPoster mEventBusPoster;
29 |
30 | public LoginUseCaseSync(LoginHttpEndpointSync loginHttpEndpointSync,
31 | AuthTokenCache authTokenCache,
32 | EventBusPoster eventBusPoster) {
33 | mLoginHttpEndpointSync = loginHttpEndpointSync;
34 | mAuthTokenCache = authTokenCache;
35 | mEventBusPoster = eventBusPoster;
36 | }
37 |
38 | public UseCaseResult loginSync(String username, String password) {
39 | LoginHttpEndpointSync.EndpointResult endpointEndpointResult;
40 | try {
41 | endpointEndpointResult = mLoginHttpEndpointSync.loginSync(username, password);
42 | } catch (NetworkErrorException e) {
43 | return UseCaseResult.NETWORK_ERROR;
44 | }
45 |
46 | if (isSuccessfulEndpointResult(endpointEndpointResult)) {
47 | mAuthTokenCache.cacheAuthToken(endpointEndpointResult.getAuthToken());
48 | mEventBusPoster.postEvent(new LoggedInEvent());
49 | return UseCaseResult.SUCCESS;
50 | } else {
51 | return UseCaseResult.FAILURE;
52 | }
53 | }
54 |
55 | private boolean isSuccessfulEndpointResult(LoginHttpEndpointSync.EndpointResult endpointResult) {
56 | return endpointResult.getStatus() == LoginHttpEndpointSync.EndpointResultStatus.SUCCESS;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/sync/authtoken/AuthTokenCache.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.sync.authtoken;
2 |
3 | /**
4 | * Created by Anjan Debnath on 7/23/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public interface AuthTokenCache {
8 |
9 | void cacheAuthToken(String authToken);
10 |
11 | String getAuthToken();
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/sync/eventbus/EventBusPoster.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.sync.eventbus;
2 |
3 | /**
4 | * Created by Anjan Debnath on 7/23/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public interface EventBusPoster {
8 |
9 | void postEvent(Object event);
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/sync/eventbus/LoggedInEvent.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.sync.eventbus;
2 |
3 | /**
4 | * Created by Anjan Debnath on 7/23/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public class LoggedInEvent {}
8 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/sync/networking/LoginHttpEndpointSync.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.sync.networking;
2 |
3 | /**
4 | * Created by Anjan Debnath on 7/23/2018.
5 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
6 | */
7 | public interface LoginHttpEndpointSync {
8 |
9 | /**
10 | * Log in using provided credentials
11 | * @return the aggregated result of login operation
12 | * @throws NetworkErrorException if login attempt failed due to network error
13 | */
14 | EndpointResult loginSync(String username, String password) throws NetworkErrorException;
15 |
16 | enum EndpointResultStatus {
17 | SUCCESS,
18 | AUTH_ERROR,
19 | SERVER_ERROR,
20 | GENERAL_ERROR
21 | }
22 |
23 | class EndpointResult {
24 | private final EndpointResultStatus mStatus;
25 | private final String mAuthToken;
26 |
27 | public EndpointResult(EndpointResultStatus status, String authToken) {
28 | mStatus = status;
29 | mAuthToken = authToken;
30 | }
31 |
32 | public EndpointResultStatus getStatus() {
33 | return mStatus;
34 | }
35 |
36 | public String getAuthToken() {
37 | return mAuthToken;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/anjan/mockitounittesttutorial/sync/networking/NetworkErrorException.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.sync.networking;
2 |
3 |
4 | /**
5 | * Created by Anjan Debnath on 7/23/2018.
6 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
7 | */
8 | public class NetworkErrorException extends Exception {
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MockitoUnitTestTutorial
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/anjan/mockitounittesttutorial/LocatorTest.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial;
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 | import org.junit.runner.RunWith;
6 | import org.mockito.ArgumentCaptor;
7 | import org.mockito.Mock;
8 | import org.mockito.junit.MockitoJUnitRunner;
9 |
10 | import static org.hamcrest.CoreMatchers.equalTo;
11 | import static org.hamcrest.CoreMatchers.is;
12 | import static org.junit.Assert.assertThat;
13 | import static org.mockito.ArgumentMatchers.any;
14 | import static org.mockito.Mockito.verify;
15 | import static org.mockito.Mockito.when;
16 |
17 |
18 | /**
19 | * Created by Anjan Debnath on 7/24/2018.
20 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
21 | */
22 | @RunWith(MockitoJUnitRunner.class)
23 | public class LocatorTest {
24 |
25 | //region constants
26 | public static final int POINT_X = 1;
27 | public static final int POINT_Y = 1;
28 | //endregion constants
29 |
30 | //region helper fields
31 |
32 | //endregion helper fields
33 | Locator SUT;
34 | @Mock
35 | LocatorService locatorServiceMock;
36 |
37 | @Before
38 | public void setup() throws Exception {
39 |
40 | SUT = new Locator(locatorServiceMock);
41 |
42 | }
43 |
44 | //region readme
45 | /**
46 | * we will use Argument Captor AC to verify mock object.
47 | * Assert must be called after any verify with AC.
48 | */
49 | //endregion readme
50 | @Test
51 | public void locator_passPositiveValueToLocatorService_success() {
52 | ArgumentCaptor pointAc = ArgumentCaptor.forClass(Point.class);
53 | SUT.locate(POINT_X, POINT_Y);
54 | verify(locatorServiceMock).geoLocate(pointAc.capture());
55 | Point point = pointAc.getValue();
56 | assertThat(point.getX(), is(equalTo(POINT_X)));
57 | assertThat(point.getY(), is(equalTo(POINT_Y)));
58 | }
59 |
60 | @Test
61 | public void locator_passNegativeValue_positiveReturn() {
62 |
63 | Point point = SUT.locate(-1, -1);
64 | assertThat(point.getX(), is(POINT_X));
65 | }
66 |
67 |
68 | //region readme
69 | /**
70 | * when the test class's method return any result
71 | * that is dependent to the mock object then that
72 | * mock object should be stubbed.
73 | */
74 | //endregion readme
75 | @Test
76 | public void locator_positiveValue_returnPointSuccess() {
77 |
78 | //Stubbing locator service
79 | when(locatorServiceMock.geoLocate(any(Point.class))).thenReturn(new Point(POINT_X, POINT_Y));
80 |
81 | Point point = SUT.locate(POINT_X, POINT_Y);
82 | assertThat(point.getX(), is(POINT_X));
83 |
84 | }
85 |
86 | //region helper methods
87 |
88 | //endregion helper methods
89 |
90 | //region helper classes
91 |
92 | //endregion helper classes
93 |
94 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/anjan/mockitounittesttutorial/async/DummyCallerTest.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.async;
2 |
3 | import org.junit.After;
4 | import org.junit.AfterClass;
5 | import org.junit.Before;
6 | import org.junit.BeforeClass;
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import org.mockito.ArgumentCaptor;
11 | import org.mockito.Captor;
12 | import org.mockito.Mock;
13 | import org.mockito.MockitoAnnotations;
14 | import org.mockito.invocation.InvocationOnMock;
15 | import org.mockito.junit.MockitoJUnitRunner;
16 | import org.mockito.stubbing.Answer;
17 |
18 | import java.util.Arrays;
19 | import java.util.List;
20 |
21 | import static org.hamcrest.CoreMatchers.equalTo;
22 | import static org.hamcrest.CoreMatchers.is;
23 | import static org.mockito.Mock.*;
24 | import static org.mockito.Mockito.*;
25 | import static org.junit.Assert.*;
26 | import static org.mockito.ArgumentCaptor.*;
27 |
28 |
29 |
30 | /**
31 | * Created by Anjan Debnath on 7/23/2018.
32 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
33 | */
34 | @RunWith(MockitoJUnitRunner.class)
35 | public class DummyCallerTest {
36 |
37 | //region constants
38 |
39 | //endregion constants
40 |
41 | //region helper fields
42 | @Mock
43 | private DummyCollaborator mDummyCollaboratorMock;
44 |
45 | //endregion helper fields
46 |
47 | DummyCaller SUT;
48 |
49 | @Before
50 | public void setup() throws Exception {
51 | MockitoAnnotations.initMocks(this);
52 | SUT = new DummyCaller(mDummyCollaboratorMock);
53 |
54 | }
55 |
56 | @Test
57 | /**
58 | * stubbing a method with a generic Answer
59 | * since we need a callback to return immediately (synchronously),
60 | * we generate an answer so when the method under test is called,
61 | * the callback will be executed right away with the data we tell it to return.
62 | */
63 | public void test_doSomethingAsynchronously_usingDoAnswer() {
64 | //arrange
65 | //here we stub the result
66 | final List results = Arrays.asList("One", "Two", "Three");
67 | doAnswer(new Answer() {
68 | @Override
69 | public Object answer(InvocationOnMock invocation) throws Throwable {
70 |
71 | ((DummyCallback)invocation.getArguments()[0]).onSuccess(results);
72 | return null;
73 | }
74 | }).when(mDummyCollaboratorMock).doSomethingAsynchronously(any(DummyCallback.class));
75 | //action
76 | SUT.doSomethingAsynchronously();
77 | //assert
78 | verify(mDummyCollaboratorMock).doSomethingAsynchronously(any(DummyCallback.class));
79 | assertThat(SUT.getResult(), is(equalTo(results)));
80 | }
81 |
82 | @Test
83 | public void test_doSomethingAsynchronously_usingArgumentCaptor() {
84 |
85 | //arrange
86 | ArgumentCaptor ac = ArgumentCaptor.forClass(DummyCallback.class);
87 | List results = Arrays.asList("One", "Two", "Three");
88 | //action
89 | SUT.doSomethingAsynchronously();
90 |
91 | //assert
92 | verify(mDummyCollaboratorMock).doSomethingAsynchronously(ac.capture());
93 | // Some assertion about the state before the callback is called
94 | assertThat(SUT.getResult().isEmpty(), is(true));
95 |
96 | //trigger the reply on callbackCaptor.getValue().
97 | ac.getValue().onSuccess(results);
98 |
99 | //Some assertion about the state after the callback is called
100 | assertThat(SUT.getResult(), is(equalTo(results)));
101 |
102 | }
103 |
104 | //region helper methods
105 |
106 | //endregion helper methods
107 |
108 | //region helper classes
109 |
110 | //endregion helper classes
111 |
112 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/anjan/mockitounittesttutorial/async/db/CustomerDaoTest.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.async.db;
2 |
3 | import com.anjan.mockitounittesttutorial.mock.Customer;
4 |
5 | import org.junit.Before;
6 | import org.junit.Test;
7 | import org.junit.runner.RunWith;
8 | import org.mockito.Mock;
9 | import org.mockito.invocation.InvocationOnMock;
10 | import org.mockito.junit.MockitoJUnitRunner;
11 | import org.mockito.stubbing.Answer;
12 |
13 | import static org.mockito.ArgumentMatchers.any;
14 | import static org.mockito.Mockito.doAnswer;
15 | import static org.mockito.Mockito.verify;
16 |
17 |
18 | /**
19 | * Created by Anjan Debnath on 8/6/2018.
20 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
21 | */
22 | @RunWith(MockitoJUnitRunner.class)
23 | public class CustomerDaoTest {
24 | public static final String JOHN = "John";
25 | public static final String DOUVER = "Douver";
26 |
27 | //region constants
28 |
29 | //endregion constants
30 |
31 | //region helper fields
32 | @Mock
33 | EntityManager entityManagerMock;
34 | @Mock
35 | Logger loggerMock;
36 | //endregion helper fields
37 |
38 | private CustomerDao SUT;
39 |
40 | @Before
41 | public void setup() throws Exception {
42 |
43 | SUT = new CustomerDao(entityManagerMock,loggerMock);
44 |
45 | }
46 |
47 | @Test
48 | public void dao_whenCustomerSaved_returnedCustomerId() {
49 |
50 | //arrange
51 | doAnswer(new Answer() {
52 | @Override
53 | public Object answer(InvocationOnMock invocation) throws Throwable {
54 | Customer customer = (Customer) invocation.getArguments()[0];
55 | customer.setId(123L);
56 | return null;
57 | }
58 | }).when(entityManagerMock).persist(any(Customer.class));
59 |
60 | //action
61 | SUT.saveCustomer(JOHN, DOUVER);
62 | //assert
63 | verify(loggerMock).info("Saved customer with id {}", 123L);
64 |
65 | }
66 |
67 | //region helper methods
68 |
69 | //endregion helper methods
70 |
71 | //region helper classes
72 |
73 | //endregion helper classes
74 |
75 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/anjan/mockitounittesttutorial/mock/LateInvoiceNotifierTest.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.mock;
2 |
3 | import org.junit.After;
4 | import org.junit.AfterClass;
5 | import org.junit.Before;
6 | import org.junit.BeforeClass;
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import org.mockito.ArgumentCaptor;
11 | import org.mockito.Mock;
12 | import org.mockito.junit.MockitoJUnitRunner;
13 |
14 | import static org.mockito.Mock.*;
15 | import static org.mockito.Mockito.*;
16 | import static org.hamcrest.CoreMatchers.*;
17 | import static org.junit.Assert.*;
18 | import static org.mockito.ArgumentCaptor.*;
19 | import static org.mockito.ArgumentMatchers.*;
20 |
21 |
22 | /**
23 | * Created by Anjan Debnath on 7/25/2018.
24 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
25 | */
26 | @RunWith(MockitoJUnitRunner.class)
27 | public class LateInvoiceNotifierTest {
28 |
29 | //region constants
30 |
31 | //endregion constants
32 |
33 | //region helper fields
34 | private Customer sampleCustomer;
35 | @Mock
36 | EmailSender mEmailSenderMock;
37 | @Mock
38 | InvoiceStorage mInvoiceStorageMock;
39 | @Mock
40 | EventRecorder mEventRecorderMock;
41 | //endregion helper fields
42 |
43 | //Class to be tested
44 | LateInvoiceNotifier SUT;
45 |
46 | @Before
47 | public void setup() throws Exception {
48 |
49 | SUT = new LateInvoiceNotifier(mEmailSenderMock, mInvoiceStorageMock, mEventRecorderMock);
50 |
51 | //set once and used by all methods
52 | sampleCustomer = new Customer();
53 | sampleCustomer.setFirstName("Harie");
54 | sampleCustomer.setLastName("Kane");
55 |
56 |
57 | }
58 |
59 | @Test
60 | public void notifier_foundLateInvoice_emailSendSuccess() throws Exception{
61 |
62 | //arrange
63 | //by stubbing we can return the value that will be true or false
64 | when(mInvoiceStorageMock.hasOutstandingInvoice(sampleCustomer)).thenReturn(true);
65 |
66 | //action
67 | SUT.notifyLate(sampleCustomer);
68 |
69 | //assert
70 | verify(mEmailSenderMock).sendEmail(sampleCustomer);
71 |
72 | }
73 |
74 | @Test
75 | public void notifier_noLateInvoice_emailSendFailed() {
76 |
77 | //arrange
78 | when(mInvoiceStorageMock.hasOutstandingInvoice(sampleCustomer)).thenReturn(false);
79 |
80 | //action
81 | SUT.notifyLate(sampleCustomer);
82 |
83 | /**
84 | * we want to make sure that the email method is NOT called.
85 | * Therefore, we also add the times argument to restrict
86 | * the number of times this method was (not) called.
87 | * If times is omitted it is assumed to be 1, which is what we do in the first test.
88 | */
89 | //assert
90 | verify(mEmailSenderMock, times(0)).sendEmail(sampleCustomer);
91 |
92 | }
93 |
94 | @Test
95 | public void notifier_foundLateInvoice_eventWithAC() {
96 |
97 | //arrange
98 | ArgumentCaptor myCaptor = ArgumentCaptor.forClass(Event.class);
99 | when(mInvoiceStorageMock.hasOutstandingInvoice(sampleCustomer)).thenReturn(true);
100 |
101 | //action
102 | SUT.notifyLate(sampleCustomer);
103 |
104 | //assert
105 | verify(mEmailSenderMock).sendEmail(sampleCustomer);
106 |
107 | verify(mEventRecorderMock).recordEvent(myCaptor.capture());
108 |
109 | Event eventThatWasSent = myCaptor.getValue();
110 | assertNotNull(eventThatWasSent.getTimestamp());
111 | assertEquals(Event.Type.REMINDER_SENT, eventThatWasSent.getType());
112 | assertEquals("Susan Ivanova",eventThatWasSent.getCustomerName());
113 | }
114 |
115 | //region helper methods
116 |
117 |
118 | //endregion helper methods
119 |
120 | //region helper classes
121 |
122 | //endregion helper classes
123 |
124 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/anjan/mockitounittesttutorial/stub/CustomerReaderTest.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.stub;
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 | import org.junit.runner.RunWith;
6 |
7 | import org.mockito.Mock;
8 | import org.mockito.junit.MockitoJUnitRunner;
9 |
10 | import static org.hamcrest.CoreMatchers.equalTo;
11 | import static org.hamcrest.CoreMatchers.is;
12 | import static org.junit.Assert.assertThat;
13 | import static org.mockito.Mockito.when;
14 |
15 |
16 | /**
17 | * Created by Anjan Debnath on 7/25/2018.
18 | * Copyright (c) 2018, W3 Engineers Ltd. All rights reserved.
19 | */
20 | @RunWith(MockitoJUnitRunner.class)
21 | public class CustomerReaderTest {
22 |
23 | //region constants
24 | private static final long CUSTOMER_ID = 1L;
25 | private static final String CUSTOMER_NAME = "customer Name";
26 | public static final String FIRST_NAME = "Customer";
27 | public static final String LAST_NAME = "Name";
28 | //endregion constants
29 |
30 | //region helper fields
31 | @Mock
32 | DbManager dbManagerMock;
33 | //endregion helper fields
34 |
35 | CustomerReader SUT;
36 |
37 | @Before
38 | public void setup() throws Exception {
39 |
40 | SUT = new CustomerReader(dbManagerMock);
41 |
42 | }
43 |
44 | @Test
45 | public void test_customerIdPassed_nameReturned() {
46 |
47 | //arrange
48 | Customer customer = new Customer();
49 | customer.setFirstName(FIRST_NAME);
50 | customer.setLastName(LAST_NAME);
51 | when(dbManagerMock.findCustomer(CUSTOMER_ID)).thenReturn(customer);
52 | //action
53 | String name = SUT.findName(CUSTOMER_ID);
54 | //assert
55 | assertThat(name, is(equalTo(CUSTOMER_NAME)));
56 | }
57 |
58 |
59 | //region helper methods
60 |
61 | //endregion helper methods
62 |
63 | //region helper classes
64 |
65 | //endregion helper classes
66 |
67 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/anjan/mockitounittesttutorial/sync/LoginUseCaseSyncTest.java:
--------------------------------------------------------------------------------
1 | package com.anjan.mockitounittesttutorial.sync;
2 |
3 |
4 |
5 | import com.anjan.mockitounittesttutorial.sync.authtoken.AuthTokenCache;
6 | import com.anjan.mockitounittesttutorial.sync.eventbus.EventBusPoster;
7 | import com.anjan.mockitounittesttutorial.sync.eventbus.LoggedInEvent;
8 | import com.anjan.mockitounittesttutorial.sync.networking.LoginHttpEndpointSync;
9 | import com.anjan.mockitounittesttutorial.sync.networking.NetworkErrorException;
10 |
11 | import org.junit.Before;
12 | import org.junit.Test;
13 | import org.mockito.ArgumentCaptor;
14 |
15 | import java.util.List;
16 |
17 | import static org.hamcrest.CoreMatchers.instanceOf;
18 | import static org.hamcrest.CoreMatchers.is;
19 | import static org.junit.Assert.assertThat;
20 | import static org.mockito.ArgumentMatchers.any;
21 | import static org.mockito.Mockito.doThrow;
22 | import static org.mockito.Mockito.mock;
23 | import static org.mockito.Mockito.times;
24 | import static org.mockito.Mockito.verify;
25 | import static org.mockito.Mockito.verifyNoMoreInteractions;
26 | import static org.mockito.Mockito.when;
27 |
28 | public class LoginUseCaseSyncTest {
29 |
30 | public static final String USERNAME = "username";
31 | public static final String PASSWORD = "password";
32 | public static final String AUTH_TOKEN = "authToken";
33 |
34 | LoginHttpEndpointSync mLoginHttpEndpointSyncMock;
35 | AuthTokenCache mAuthTokenCacheMock;
36 | EventBusPoster mEventBusPosterMock;
37 |
38 | LoginUseCaseSync SUT;
39 |
40 | @Before
41 | public void setup() throws Exception {
42 | mLoginHttpEndpointSyncMock = mock(LoginHttpEndpointSync.class);
43 | mAuthTokenCacheMock = mock(AuthTokenCache.class);
44 | mEventBusPosterMock = mock(EventBusPoster.class);
45 | SUT = new LoginUseCaseSync(mLoginHttpEndpointSyncMock, mAuthTokenCacheMock, mEventBusPosterMock);
46 | successEndPintResult();
47 | }
48 |
49 | @Test
50 | public void loginSync_success_usernameAndPasswordPassedToEndpoint() throws Exception {
51 | ArgumentCaptor ac = ArgumentCaptor.forClass(String.class);
52 | SUT.loginSync(USERNAME, PASSWORD);
53 | verify(mLoginHttpEndpointSyncMock, times(1)).loginSync(ac.capture(), ac.capture());
54 | List captures = ac.getAllValues();
55 | assertThat(captures.get(0), is(USERNAME));
56 | assertThat(captures.get(1), is(PASSWORD));
57 | }
58 |
59 | @Test
60 | public void loginSync_success_authTokenCached() throws Exception {
61 | ArgumentCaptor ac = ArgumentCaptor.forClass(String.class);
62 | SUT.loginSync(USERNAME, PASSWORD);
63 | verify(mAuthTokenCacheMock).cacheAuthToken(ac.capture());
64 | assertThat(ac.getValue(), is(AUTH_TOKEN));
65 | }
66 |
67 | @Test
68 | public void loginSync_generalError_authTokenNotCached() throws Exception {
69 | generalError();
70 | SUT.loginSync(USERNAME, PASSWORD);
71 | verifyNoMoreInteractions(mAuthTokenCacheMock);
72 | }
73 |
74 | @Test
75 | public void loginSync_authError_authTokenNotCached() throws Exception {
76 | authError();
77 | SUT.loginSync(USERNAME, PASSWORD);
78 | verifyNoMoreInteractions(mAuthTokenCacheMock);
79 | }
80 |
81 | @Test
82 | public void loginSync_serverError_authTokenNotCached() throws Exception {
83 | serverError();
84 | SUT.loginSync(USERNAME, PASSWORD);
85 | verifyNoMoreInteractions(mAuthTokenCacheMock);
86 | }
87 |
88 | @Test
89 | public void loginSync_success_loggedInEventPosted() throws Exception {
90 | ArgumentCaptor ac = ArgumentCaptor.forClass(Object.class);
91 | SUT.loginSync(USERNAME, PASSWORD);
92 | verify(mEventBusPosterMock).postEvent(ac.capture());
93 | assertThat(ac.getValue(), is(instanceOf(LoggedInEvent.class)));
94 | }
95 |
96 | @Test
97 | public void loginSync_generalError_noInteractionWithEventBusPoster() throws Exception {
98 | generalError();
99 | SUT.loginSync(USERNAME, PASSWORD);
100 | verifyNoMoreInteractions(mEventBusPosterMock);
101 | }
102 |
103 | @Test
104 | public void loginSync_authError_noInteractionWithEventBusPoster() throws Exception {
105 | authError();
106 | SUT.loginSync(USERNAME, PASSWORD);
107 | verifyNoMoreInteractions(mEventBusPosterMock);
108 | }
109 |
110 | @Test
111 | public void loginSync_serverError_noInteractionWithEventBusPoster() throws Exception {
112 | serverError();
113 | SUT.loginSync(USERNAME, PASSWORD);
114 | verifyNoMoreInteractions(mEventBusPosterMock);
115 | }
116 |
117 | @Test
118 | public void loginSync_success_successReturned() throws Exception {
119 | LoginUseCaseSync.UseCaseResult result = SUT.loginSync(USERNAME, PASSWORD);
120 | assertThat(result, is(LoginUseCaseSync.UseCaseResult.SUCCESS));
121 | }
122 |
123 | @Test
124 | public void loginSync_serverError_failureReturned() throws Exception {
125 | serverError();
126 | LoginUseCaseSync.UseCaseResult result = SUT.loginSync(USERNAME, PASSWORD);
127 | assertThat(result, is(LoginUseCaseSync.UseCaseResult.FAILURE));
128 | }
129 |
130 | @Test
131 | public void loginSync_authError_failureReturned() throws Exception {
132 | authError();
133 | LoginUseCaseSync.UseCaseResult result = SUT.loginSync(USERNAME, PASSWORD);
134 | assertThat(result, is(LoginUseCaseSync.UseCaseResult.FAILURE));
135 | }
136 |
137 | @Test
138 | public void loginSync_generalError_failureReturned() throws Exception {
139 | generalError();
140 | LoginUseCaseSync.UseCaseResult result = SUT.loginSync(USERNAME, PASSWORD);
141 | assertThat(result, is(LoginUseCaseSync.UseCaseResult.FAILURE));
142 | }
143 |
144 | @Test
145 | public void loginSync_networkError_networkErrorReturned() throws Exception {
146 | networkError();
147 | LoginUseCaseSync.UseCaseResult result = SUT.loginSync(USERNAME, PASSWORD);
148 | assertThat(result, is(LoginUseCaseSync.UseCaseResult.NETWORK_ERROR));
149 | }
150 |
151 | private void networkError() throws Exception {
152 | doThrow(new NetworkErrorException())
153 | .when(mLoginHttpEndpointSyncMock).loginSync(any(String.class), any(String.class));
154 | }
155 |
156 |
157 | //STUB
158 | private void successEndPintResult() throws NetworkErrorException {
159 | when(mLoginHttpEndpointSyncMock.loginSync(any(String.class), any(String.class)))
160 | .thenReturn(new LoginHttpEndpointSync.EndpointResult(LoginHttpEndpointSync.EndpointResultStatus.SUCCESS, AUTH_TOKEN));
161 | }
162 |
163 | private void generalError() throws Exception {
164 | when(mLoginHttpEndpointSyncMock.loginSync(any(String.class), any(String.class)))
165 | .thenReturn(new LoginHttpEndpointSync.EndpointResult(LoginHttpEndpointSync.EndpointResultStatus.GENERAL_ERROR, ""));
166 | }
167 |
168 | private void authError() throws Exception {
169 | when(mLoginHttpEndpointSyncMock.loginSync(any(String.class), any(String.class)))
170 | .thenReturn(new LoginHttpEndpointSync.EndpointResult(LoginHttpEndpointSync.EndpointResultStatus.AUTH_ERROR, ""));
171 | }
172 |
173 | private void serverError() throws Exception {
174 | when(mLoginHttpEndpointSyncMock.loginSync(any(String.class), any(String.class)))
175 | .thenReturn(new LoginHttpEndpointSync.EndpointResult(LoginHttpEndpointSync.EndpointResultStatus.SERVER_ERROR, ""));
176 | }
177 |
178 | }
--------------------------------------------------------------------------------
/assets/Unit test Documentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/assets/Unit test Documentation.pdf
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.5.0'
11 |
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/doc/FOSS MileStone 2.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/doc/FOSS MileStone 2.pptx
--------------------------------------------------------------------------------
/doc/FOSS Milestone 1.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/doc/FOSS Milestone 1.pptx
--------------------------------------------------------------------------------
/doc/Pull request and merge conflict with rebase.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/doc/Pull request and merge conflict with rebase.pdf
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | <<<<<<< HEAD
2 | #Tue Aug 27 13:35:10 BDT 2019
3 | =======
4 | #Mon Aug 26 16:38:53 BDT 2019
5 | >>>>>>> loical changes
6 | distributionBase=GRADLE_USER_HOME
7 | distributionPath=wrapper/dists
8 | zipStoreBase=GRADLE_USER_HOME
9 | zipStorePath=wrapper/dists
10 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
11 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Unit test with Mockito
2 |
3 | *Ackwoledgement* : This Project is created for getting familiar with Mockito JUnit test.
4 | This repository is created by taking reference from following links:
5 |
6 | - https://automationrhapsody.com/mock-junit-tests-mockito-example/
7 | - https://semaphoreci.com/community/tutorials/stubbing-and-mocking-with-mockito-2-and-junit
8 | - https://hackernoon.com/objects-vs-data-structures-e380b962c1d2
9 | - https://stackoverflow.com/questions/36253040/example-on-mockitos-argumentcaptor
10 | - https://javacodehouse.com/blog/junit-tutorial/
11 | - http://www.baeldung.com/mockito-annotations
12 | - https://javacodehouse.com/blog/mockito-tutorial/
13 |
14 |
15 |
16 | ## Custom template create for Junit4
17 |
18 | From Android studio go to In the top menu, go to `file > Settings`
19 | and in the settings. In the left menu, find `Editor > File and Code templates` and click on the `Code Tab`
20 | and find `Junit4 Test Class`.
21 |
22 | 
23 |
24 |
25 | - Now its time to create a custom template for unit test
26 | - Just copy and paste this and get some pre defined imports and methods.
27 |
28 | ````
29 | import org.junit.After;
30 | import org.junit.AfterClass;
31 | import org.junit.Before;
32 | import org.junit.BeforeClass;
33 | import org.junit.Test;
34 | import org.junit.runner.RunWith;
35 |
36 | import org.mockito.junit.MockitoJUnitRunner;
37 | import static org.mockito.Mock.*;
38 | import static org.mockito.Mockito.*;
39 | import static org.hamcrest.CoreMatchers.*;
40 | import static org.junit.Assert.*;
41 | import static org.mockito.ArgumentCaptor.*;
42 | import static org.mockito.ArgumentMatchers.*;
43 |
44 |
45 |
46 | #parse("File Header.java")
47 | @RunWith(MockitoJUnitRunner.class)
48 | public class ${NAME} {
49 |
50 | //region constants
51 |
52 | //endregion constants
53 |
54 | //region helper fields
55 |
56 | //endregion helper fields
57 |
58 | ${CLASS_NAME} SUT;
59 |
60 | @Before
61 | public void setup() throws Exception{
62 |
63 | SUT = new ${CLASS_NAME} ();
64 | ${BODY}
65 | }
66 |
67 | //region helper methods
68 |
69 | //endregion helper methods
70 |
71 | //region helper classes
72 |
73 | //endregion helper classes
74 |
75 | }
76 | ````
77 |
78 |
79 | ### From where you start?
80 |
81 | you will find the slides [here](https://github.com/anjandebnath/MockitoUnitTestTutorial/tree/master/slides)
82 |
83 | Find the documentation [here](https://github.com/anjandebnath/MockitoUnitTestTutorial/tree/master/assets)
84 |
85 | This will give you the basic idea about unit test.
86 |
87 | start exploring the code from this sequence
88 |
89 | under `test` package
90 | - LocatorTest
91 | - stub-> CustomerReaderTest
92 | - mock-> LateInvoiceNotifierTest
93 | - sync-> LoginUseCaseSyncTest
94 | - async-> DummyCallerTest
95 |
96 | Thanks
97 |
98 | Anjan Debnath
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/slides/Unit test-1.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/slides/Unit test-1.pptx
--------------------------------------------------------------------------------
/slides/Unit test-2.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/slides/Unit test-2.pptx
--------------------------------------------------------------------------------
/slides/Unit test-3.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anjandebnath/MockitoUnitTestTutorial/71c1c4ae93d0d9fbb5ddab80af6b96cf1c1a69ea/slides/Unit test-3.pptx
--------------------------------------------------------------------------------