- 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.
- Spring 5企業級開發實戰
- Visual FoxPro程序設計教程(第3版)
- Reactive Programming with Swift
- Scala Design Patterns
- Java開發入行真功夫
- 大學計算機基礎(第2版)(微課版)
- 3D少兒游戲編程(原書第2版)
- The HTML and CSS Workshop
- Learning Data Mining with R
- Active Directory with PowerShell
- 用戶體驗可視化指南
- HTML5開發精要與實例詳解
- Django實戰:Python Web典型模塊與項目開發
- Qt5 C++ GUI Programming Cookbook
- Mastering Apache Camel