- Learning Android Application Testing
- Paul Blundell Diego Torres Milano
- 867字
- 2021-07-23 19:58:55
Mock objects
We have seen the mock objects provided by the Android testing framework in Chapter 1, Getting Started with Testing, and evaluated the concerns about not using real objects to isolate our tests from the surrounding environment.
The next chapter deals with Test-driven Development, and if we were Test-driven Development purists, we can argue about the use of mock objects and be more inclined to use real ones. Martin Fowler calls these two styles the classical and mockist Test-driven Development dichotomy in his great article Mocks aren't stubs, which can be read online at http://www.martinfowler.com/articles/mocksArentStubs.html.
Independent of this discussion, we are introducing mock objects as one of the available building blocks because, sometimes, using mock objects in our tests is recommended, desirable, useful, or even unavoidable.
The Android SDK provides the following classes in the subpackage android.test.mock
to help us:
MockApplication
: This is a mock implementation of theApplication
class. All methods are non-functional and throwUnsupportedOperationException
.MockContentProvider
: This is a mock implementation ofContentProvider
. All methods are non-functional and throwUnsupportedOperationException
.MockContentResolver
: This is a mock implementation of theContentResolver
class that isolates the test code from the real content system. All methods are non-functional and throwUnsupportedOperationException
.MockContext
: This is a mock context class, and this can be used to inject other dependencies. All methods are non-functional and throwUnsupportedOperationException
.MockCursor
: This is a mock Cursor class that isolates the test code from real Cursor implementation. All methods are non-functional and throwUnsupportedOperationException
.MockDialogInterface
: This is a mock implementation of theDialogInterface
class. All methods are non-functional and throwUnsupportedOperationException
.MockPackageManager
: This is a mock implementation of thePackageManager
class. All methods are non-functional and throwUnsupportedOperationException
.MockResources
: This is a mockResources
class.
All of these classes have non-functional methods that throw UnsupportedOperationException
when used. If you need to use some of these methods, or if you detect that your test is failing with this Exception
, you should extend one of these base classes and provide the required functionality.
An overview of MockContext
This mock can be used to inject other dependencies, mocks, or monitors into the classes under test. Extend this class to provide your desired behavior, overriding the correspondent methods. The Android SDK provides some prebuilt mock Context
objects, each of which has a separate use case.
The IsolatedContext class
In your tests, you might find the need to isolate the Activity under test from other Android components to prevent unwanted interactions. This can be a complete isolation, but sometimes, this isolation avoids interacting with other components, and for your Activity to still run correctly, some connection with the system is required.
For those cases, the Android SDK provides android.test.IsolatedContext
, a mock Context
that not only prevents interaction with most of the underlying system but also satisfies the needs of interacting with other packages or components such as Services
or ContentProviders
.
Alternate route to file and database operations
In some cases, all we need is to be able to provide an alternate route to the file and database operations. For example, if we are testing the application on a real device, we perhaps don't want to affect the existing database but use our own testing data.
Such cases can take advantage of another class that is not part of the android.test.mock
subpackage but is part of android.test
instead, that is, RenamingDelegatingContext
.
This class lets us alter operations on files and databases by having a prefix that is specified in the constructor. All other operations are delegated to the delegating Context that you must specify in the constructor too.
Suppose our Activity
under test uses a database we want to control, probably introducing specialized content or fixture data to drive our tests, and we don't want to use the real files. In this case, we create a RenamingDelegatingContext
class that specifies a prefix, and our unchanged Activity will use this prefix to create any files.
For example, if our Activity tries to access a file named birthdays.txt
, and we provide a RenamingDelegatingContext
class that specifies the prefix test
, then this same Activity will access the file testbirthdays.txt
instead when it is being tested.
The MockContentResolver class
The MockContentResolver
class implements all methods in a non-functional way and throws the exception UnsupportedOperationException
if you attempt to use them. The reason for this class is to isolate tests from the real content.
Let's say your application uses a ContentProvider
class to feed your Activity information. You can create unit tests for this ContentProvider
using ProviderTestCase2
, which we will be analyzing shortly, but when we try to produce functional or integration tests for the Activity against ContentProvider
, it's not so evident as to what test case to use. The most obvious choice is ActivityInstrumentationTestCase2
, mainly if your functional tests simulate user experience because you might need the sendKeys()
method or similar methods, which are readily available on these tests.
The first problem you might encounter then is that it's unclear as to where to inject a MockContentResolver
in your test to be able to use test data with your ContentProvider
. There's no way to inject a MockContext
either.
This problem will be solved in Chapter 3, Baking with Testing Recipes where further details are provided.
- 手機安全和可信應用開發指南:TrustZone與OP-TEE技術詳解
- iOS面試一戰到底
- C語言程序設計實訓教程
- 編寫高質量代碼:改善Python程序的91個建議
- C語言程序設計習題與實驗指導
- Arduino電子設計實戰指南:零基礎篇
- Java自然語言處理(原書第2版)
- Analytics for the Internet of Things(IoT)
- Mastering R for Quantitative Finance
- PHP程序設計經典300例
- Spring Microservices
- C#從入門到精通(微視頻精編版)
- 測試架構師修煉之道:從測試工程師到測試架構師(第2版)
- Java Web開發系統項目教程
- Data Visualization:Representing Information on Modern Web