Core Java coding question converting String to BigDecimal

There are times while coding you need to convert an entity of one data type to another or validate a given input.



Q. Can you write a generic function that converts an amount in String to double amount?
A.

Step 1: Ask the right questions and arrive at a more detailed requirements.
  • Handling negative amounts like -34.01 or (34.01) with a parenthesis. Parentheses denote a negative value. 
  • Handling commas in formatted values like 1,205.45, etc.
  • Handling negative scenarios like amount being  empty as in ( ).
Since, it is a requirement to write a generic function, all the above scenarios need to be taken care of.

Step 2: Lets use a TDD (Test Driven Development approach).

So, write a skeleton class so that all our unit tests fail.

  
package com.mycompany.app5;

import java.math.BigDecimal;
import java.text.ParseException;

public class ConvertingAmount
{

public BigDecimal convert(String amount) throws ParseException
{
BigDecimal result = null;
return result;
}
}

Next, write the unit tests based on the above requirements so that all fail, but cover the requirements.

  
package com.mycompany.app5;

import java.math.BigDecimal;
import java.text.ParseException;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;

public class ConvertingAmountTest
{
private ConvertingAmount ca;

@Before
public void setUp()
{
ca = new ConvertingAmount();
}

@Test
public void testPositiveAmount() throws ParseException
{
BigDecimal converted = ca.convert("2255.001");
Assert.assertEquals(new BigDecimal("2255.001"), converted);
}

@Test
public void testNegativeAmount() throws ParseException
{
BigDecimal converted = ca.convert("-2255.001");
Assert.assertEquals(new BigDecimal("-2255.001"), converted);
}

@Test
public void testNegativeAmountWithParanthes() throws ParseException
{
BigDecimal converted = ca.convert("(2255.001)");
Assert.assertEquals(new BigDecimal("-2255.001"), converted);
}

@Test
public void testPosiotiveAmountFormatted() throws ParseException
{
BigDecimal converted = ca.convert("2,255.001");
Assert.assertEquals(new BigDecimal("2255.001"), converted);
}

@Test
public void testNegativeAmountFormatted() throws ParseException
{
BigDecimal converted = ca.convert("-2,255.001");
Assert.assertEquals(new BigDecimal("-2255.001"), converted);
}

@Test
public void testNegativeAmountWithParenthesesFormatted() throws ParseException
{
BigDecimal converted = ca.convert("(2,255.001)");
Assert.assertEquals(new BigDecimal("-2255.001"), converted);
}

@Test(expected = ParseException.class)
public void testExceptionalScenario() throws ParseException
{
String amount = "()";
ca.convert(amount);
}

@Test(expected = ParseException.class)
public void testExceptionalScenario2() throws ParseException
{
String amount = "abc";
ca.convert(amount);
}
}




Step 3: Implement the functionality, so that all the above unit tests pass.

 
package com.mycompany.app5;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;

import org.apache.commons.lang.StringUtils;

public class ConvertingAmount
{

public BigDecimal convert(String amount) throws ParseException
{
BigDecimal result = null;

DecimalFormat df = new DecimalFormat("#,#00.00;-#,#00.00"); //positive;negative

//convert (2255.001) to -2255.001 and (2,255.001) to -2255.001
if (StringUtils.isNotBlank(amount) && amount.startsWith("(") && amount.endsWith(")"))
{
String valueStr = amount.substring(1, amount.length() - 1);
Number valInParenthesis = df.parse(valueStr.trim());
result = BigDecimal.valueOf(valInParenthesis.doubleValue()).negate();
amount = result.toPlainString();
}

//parse 2,255.001 and -2,255.001
Number val = df.parse(amount);
result = BigDecimal.valueOf(val.doubleValue());

return result;
}
}

Now, all green.


Related Posts by Categories

0 komentar:

Posting Komentar