如果以.00结尾,如何比较双打的字符串表示形式
我目前正在为我的应用程序(这是一本支票簿记录应用程序)编写ContentProvider的测试用例,并且在比较double值时我的测试失败。 说明这一点的最佳方式是使用代码。 我有这个函数返回ContentValues,以便将一个账户对象插入到数据库中:
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;
}
函数内部testInsertReadProvider()
我有以下代码,以插入该帐户:
// 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();
验证游标函数接受一个游标和一个ContentValues,并使用映射循环遍历它们来比较每个值。 这是我从一个关于创建Android应用程序的Udacity教程中学到的一种策略,所以也许有更好的方法来比较它们而不是字符串,但它看起来像这样:
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();
}
当调用assertEquals()
行时,测试失败,并且出现以下错误消息:
junit.framework.ComparisonFailure:expected:<3000 [.0]>但是:<3000 []>
它看起来像cursor.getString()方法截断小数位,如果他们等于0.如果我尝试使用值为3000.01这个测试它工作正常。 SQLite负责删除不必要的零? 我可以以某种方式更改assertEquals()
,以便这两个值的处理方式相同吗?
如果你真的想要比较字符串,那么你将不得不稍微破解一下,但是下面有一个替代方案。
首先,这是TL; DR; 码:
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));
}
}
可能发生的情况是,您的double
每个实例在最后被不同的toString()
方法投影到String
。 这是造成违规行为的原因。
你可以像我上面概述的那样破解它,或者在为每种类型专门设计的switch语句中进行比较(恕我直言,一种更好的解决方案)。
这是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));
}
}
你应该把它们转移到双打使用
double d1 = Double.parseDouble(text) double d2 = Double.parseDouble(text2)
对第二个字符串进行相同操作并比较结果。 您也可以使用abs来确保由于表示而没有区别:
assertTrue(Math.abs(d1 -d2) < 0.00001);
编辑:
我会去做这样的事情:
try
{
double d1 = Double.parseDouble(text);
double d2 = Double.parseDouble(text2);
assertTrue(Math.abs(d1-d2) < 0.00001);
}catch(NumberFormatException e)
{
assertEquals(text, text2);
}
链接地址: http://www.djcxy.com/p/84537.html
上一篇: How to compare String representations of doubles if it ends in .00