android / android/testing-samples

SharedPreferencesHelperTest is asserting a stub works

Open
#119 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
Java
Stars
9.3k
Forks
3.6k
PR merge metrics
No merged PRs in 30d

Description

I see a unit test is written for ``SharedPreferencesHelper`` in BasicTesting project as follows:

/*
* Copyright 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.android.testing.unittesting.BasicSample;

import android.content.SharedPreferences;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.Calendar;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.*;


/**
* Unit tests for the {@link SharedPreferencesHelper} that mocks {@link SharedPreferences}.
*/
@SmallTest
@RunWith(MockitoJUnitRunner.class)
public class SharedPreferencesHelperTest {

private static final String TEST_NAME = "Test name";

private static final String TEST_EMAIL = "test@email.com";

private static final Calendar TEST_DATE_OF_BIRTH = Calendar.getInstance();

static {
TEST_DATE_OF_BIRTH.set(1980, 1, 1);
}

private SharedPreferenceEntry mSharedPreferenceEntry;

private SharedPreferencesHelper mMockSharedPreferencesHelper;

private SharedPreferencesHelper mMockBrokenSharedPreferencesHelper;

@Mock
SharedPreferences mMockSharedPreferences;

@Mock
SharedPreferences mMockBrokenSharedPreferences;

@Mock
SharedPreferences.Editor mMockEditor;

@Mock
SharedPreferences.Editor mMockBrokenEditor;

@Before
public void initMocks() {
// Create SharedPreferenceEntry to persist.
mSharedPreferenceEntry = new SharedPreferenceEntry(TEST_NAME, TEST_DATE_OF_BIRTH,
TEST_EMAIL);

// Create a mocked SharedPreferences.
mMockSharedPreferencesHelper = createMockSharedPreference();

// Create a mocked SharedPreferences that fails at saving data.
mMockBrokenSharedPreferencesHelper = createBrokenMockSharedPreference();
}

@Test
public void sharedPreferencesHelper_SaveAndReadPersonalInformation() {
// Save the personal information to SharedPreferences
boolean success = mMockSharedPreferencesHelper.savePersonalInfo(mSharedPreferenceEntry);

assertThat("Checking that SharedPreferenceEntry.save... returns true",
success, is(true));

// Read personal information from SharedPreferences
SharedPreferenceEntry savedSharedPreferenceEntry =
mMockSharedPreferencesHelper.getPersonalInfo();

// Make sure both written and retrieved personal information are equal.
assertThat("Checking that SharedPreferenceEntry.name has been persisted and read correctly",
mSharedPreferenceEntry.getName(),
is(equalTo(savedSharedPreferenceEntry.getName())));
assertThat("Checking that SharedPreferenceEntry.dateOfBirth has been persisted and read "
+ "correctly",
mSharedPreferenceEntry.getDateOfBirth(),
is(equalTo(savedSharedPreferenceEntry.getDateOfBirth())));
assertThat("Checking that SharedPreferenceEntry.email has been persisted and read "
+ "correctly",
mSharedPreferenceEntry.getEmail(),
is(equalTo(savedSharedPreferenceEntry.getEmail())));
}

@Test
public void sharedPreferencesHelper_SavePersonalInformationFailed_ReturnsFalse() {
// Read personal information from a broken SharedPreferencesHelper
boolean success =
mMockBrokenSharedPreferencesHelper.savePersonalInfo(mSharedPreferenceEntry);
assertThat("Makes sure writing to a broken SharedPreferencesHelper returns false", success,
is(false));
}

/**
* Creates a mocked SharedPreferences.
*/
private SharedPreferencesHelper createMockSharedPreference() {
// Mocking reading the SharedPreferences as if mMockSharedPreferences was previously written
// correctly.
when(mMockSharedPreferences.getString(eq(SharedPreferencesHelper.KEY_NAME), anyString()))
.thenReturn(mSharedPreferenceEntry.getName());
when(mMockSharedPreferences.getString(eq(SharedPreferencesHelper.KEY_EMAIL), anyString()))
.thenReturn(mSharedPreferenceEntry.getEmail());
when(mMockSharedPreferences.getLong(eq(SharedPreferencesHelper.KEY_DOB), anyLong()))
.thenReturn(mSharedPreferenceEntry.getDateOfBirth().getTimeInMillis());

// Mocking a successful commit.
when(mMockEditor.commit()).thenReturn(true);

// Return the MockEditor when requesting it.
when(mMockSharedPreferences.edit()).thenReturn(mMockEditor);
return new SharedPreferencesHelper(mMockSharedPreferences);
}

/**
* Creates a mocked SharedPreferences that fails when writing.
*/
private SharedPreferencesHelper createBrokenMockSharedPreference() {
// Mocking a commit that fails.
when(mMockBrokenEditor.commit()).thenReturn(false);

// Return the broken MockEditor when requesting it.
when(mMockBrokenSharedPreferences.edit()).thenReturn(mMockBrokenEditor);
return new SharedPreferencesHelper(mMockBrokenSharedPreferences);
}
}

in line ``assertThat("Checking that SharedPreferenceEntry.save... returns true",
success, is(true));`` in test ``sharedPreferencesHelper_SaveAndReadPersonalInformation`` you are checking to see if ``commit`` returns ``true`` which is nonsense since you have stubbed mock Editor to return true.

Actually I think testing for this class should have two purposes:

First we should verify method ``putString`` and ``putLong`` have been called by editor in ``savePersonalInfo``.

The second one, is to ensure that ``getPersonalInfo`` have correct conversions.

I'm open to discuss my thoughts with you.
Sincerely.

Contributor guide

Open the contributing guide

Research direction

Start in SharedPreferencesHelperTest, especially sharedPreferencesHelper_SaveAndReadPersonalInformation and the createMockSharedPreference helpers. Review savePersonalInfo and getPersonalInfo in SharedPreferencesHelper, then run SharedPreferencesHelperTest. Done means the test verifies the editor's putString and putLong calls and checks the conversions performed by getPersonalInfo without relying only on stubbed commit results.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
testing
Issue type
Refactor
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.