How to compare string representations of doubles if it ends in .00

I am currently writing test cases for ContentProvider in my application (this is a checkbook writing application), and I have a test failure when it compares double values. The best way to illustrate this is with code. I have this function that returns ContentValues ​​for the account object that needs to be inserted into the database:

private ContentValues getAccountContentValues(){ String testName = "Capital One"; double testStartingBalance = 3000.00; ContentValues accountValues = new ContentValues(); accountValues.put(AccountEntry.COLUMN_NAME, testName); accountValues.put(AccountEntry.COLUMN_BALANCE, testStartingBalance); return accountValues; } 

Inside the function testInsertReadProvider() I have the following code to insert this account:

 // Get Account values and write them ContentValues accountValues = getAccountContentValues(); Uri accountInsertUri = mContext.getContentResolver().insert(AccountEntry.CONTENT_URI, accountValues); long accountRowId = ContentUris.parseId(accountInsertUri); // Verify we got a row back assertTrue(accountRowId > 0); // A cursor is the primary interface to the query results Cursor cursor = mContext.getContentResolver().query( AccountEntry.CONTENT_URI, // Table name null, // columns to be returned. Null returns all columns null, // Columns for where clause null, // Values for where clause null // Sort order ); // Validate the information read from the database. validateCursor(cursor, accountValues); cursor.close(); 

The validation function takes a cursor and ContentValues ​​and passes through them, using a map to compare each value. This is the strategy I learned from the next Udacity tutorial on creating Android apps, so there may be a better way to compare them, rather than as strings, but it looks like this:

 void validateCursor(Cursor valueCursor, ContentValues expectedValues){ assertTrue(valueCursor.moveToFirst()); Set<Map.Entry<String, Object>> valueSet = expectedValues.valueSet(); for(Map.Entry<String, Object> entry : valueSet){ String columnName = entry.getKey(); int idx = valueCursor.getColumnIndex(columnName); assertFalse(idx == -1); String expectedValue = entry.getValue().toString(); assertEquals(expectedValue, valueCursor.getString(idx)); } valueCursor.close(); } 

The test does not work when the assertEquals() line is assertEquals() and the following error message appears:

junit.framework.ComparisonFailure: expected: <3000 [.0]> but it was: <3000 []>

It seems like the cursor.getString () method truncates decimals if they are 0. If I try this test using the value 3000.01, it works fine. Will SQLite respond to dumping unnecessary zeros? Is there any way to change assertEquals() so that these two values ​​are treated the same?

+7
java android sqlite testing android-sqlite
source share
2 answers

If you really like to compare strings, you will have to hack them a bit, but there is an alternative below.

First, here is TL; DR; the code:

  for(Map.Entry<String, Object> entry : valueSet){ String columnName = entry.getKey(); int idx = valueCursor.getColumnIndex(columnName); assertFalse(idx == -1); String expectedValue = entry.getValue().toString(); if((Cursor.FIELD_TYPE_FLOAT == valueCursor.getType(idx)) && valueCursor.getDouble(idx) % 1 == 0){ assertEquals(expectedValue, valueCursor.getString(idx) + ".0"); } else { assertEquals(expectedValue, valueCursor.getString(idx)); } } 

What is probably happening is that each instance of your double at the end is projected onto a String using another toString() method. This is what causes the disturbance.

You can hack it, as I stated above, or perform a comparison in the switch instruction specially designed for each type (IMHO is the best solution).

Here is the version of Switch :

 for(Map.Entry<String, Object> entry : valueSet){ String columnName = entry.getKey(); int idx = valueCursor.getColumnIndex(columnName); assertFalse(idx == -1); switch(valueCursor.getType(idx)) { case Cursor.FIELD_TYPE_FLOAT: assertEquals(entry.getValue(), valueCursor.getDouble(idx)); break; case Cursor.FIELD_TYPE_INTEGER: //assertEquals(entry.getValue(), valueCursor.getInt(idx)); // didn't work //assertTrue((new Integer((int)entry.getValue())).equals(valueCursor.getInt(idx))); assertEquals(Integer.parseInt(entry.getValue().toString()), valueCursor.getInt(idx)); case Cursor.FIELD_TYPE_STRING: assertEquals(entry.getValue(), valueCursor.getString(idx)); break; default: assertEquals(entry.getValue().toString(), valueCursor.getString(idx)); } } 
+1
source share

You have to transfer them to paired using

double d1 = Double.parseDouble(text) double d2 = Double.parseDouble(text2)

Do the same for the second row and compare the results. You can also use abs to make sure there is no difference due to the representation:

assertTrue(Math.abs(d1 -d2) < 0.00001);

EDIT:

I would go for something like this:

 try { double d1 = Double.parseDouble(text); double d2 = Double.parseDouble(text2); assertTrue(Math.abs(d1-d2) < 0.00001); }catch(NumberFormatException e) { assertEquals(text, text2); } 
+3
source share

All Articles