当我运行 jUnit 测试时,它一直说数字格式异常,字符串没有正确的卡号长度,任何想法的代码有什么问题以及我如何能够解决这个问题?我在下面发布了测试、代码和跟踪:
测试:
@Test
public void testToString() {
assertEquals("Branch [name=Poole, address=12 Swanage Road, phoneNumber=01202123457, bankManager=Sarah Jane]", branch2.toString());
}
痕迹:
java.lang.NumberFormatException: The string "377659710738349" does not have the proper length of a card number
at prog2.as1.CardNumber.<init>(CardNumber.java:19)
at prog2.as1.BankCard.getNextCardNumber(BankCard.java:68)
at prog2.as1.BankCard.<init>(BankCard.java:54)
at prog2.as1.CurrentAccount.<init>(CurrentAccount.java:95)
at prog2.as1.test.BankCommon.setUp(BankCommon.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
卡号:
public class CardNumber extends FilteredString {
/**
* Create a new instance. After removal of spaces, dots and tabs there must
* be 16 digits left for a valid card number.
*
* @param origString The input string.
*/
public CardNumber(final String origString) {
super(origString);
if (toString().length() != 16) {
throw new NumberFormatException("The string \"" + origString + "\" does not have the proper length of a card number");
}
}
/**
* Filter out certain characters. Filters tabs, spaces and periods, Accepts
* digits.
*
* @param c {@inheritDoc}
* @param number {@inheritDoc}
*/
@Override
protected int filterCodePoint(final int c, final int pos, final String number) {
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
// Add to phone number
return c;
case ' ':
case '\t':
case '.':
// Ignore
return 0;
default:
throw new NumberFormatException("The string \"" + number + "\" does not represent a valid card number");
}
}
}
银行卡:
public class BankCard {
private static long lastNumber;
static {
Random r = new Random();
do {
lastNumber = r.nextLong() % 10000000000000000l;
} while (lastNumber < 0l);
}
/**
* An enumeration of the types of bank cards.
*
* @author Paul de Vrieze
*/
public static enum CardType {
/** A cash card. */
CashCard,
/** A debit card. */
DebitCard,
/** A credit card. */
CreditCard;
}
private CardNumber cardNumber;
private Calendar expiry;
private CardType kind;
/**
* Create a new bank card of the specified type.
*
* @param type The type of card.
*/
public BankCard(final CardType type) {
kind = type;
cardNumber = getNextCardNumber();
Calendar now = Calendar.getInstance();
expiry = new GregorianCalendar(now.get(Calendar.YEAR) + 3, now.get(Calendar.MONTH), 1);
}
/**
* Get a new 16 digit card number, randomly increased from the last one.
*
* @return A random card number.
*/
private static CardNumber getNextCardNumber() {
Random rand = new Random();
lastNumber = (lastNumber + 1 + rand.nextInt(100000)) % 1000000000000000l;
Formatter f = new Formatter();
CardNumber result = new CardNumber(f.format("%015d", Long.valueOf(lastNumber)).toString());
f.close();
return result;
}
/**
* Get the expiry date of the card.
*
* @return A calendar with the expiry date.
*/
public Calendar getExpiry() {
return expiry;
}
/**
* Set the expiry date of the card.
*
* @param expiry The new expiry date.
*/
public void setExpiry(final Calendar expiry) {
this.expiry = expiry;
}
/**
* Return the type of the card.
*
* @return The type.
*/
public CardType getKind() {
return kind;
}
/**
* Set the type of the card.
*
* @param kind The new type of the card.
*/
public void setKind(final CardType kind) {
this.kind = kind;
}
/**
* Get the number of the card.
*
* @return The card number.
*/
public CardNumber getCardNumber() {
return cardNumber;
}
/**
* Set the number of the card.
*
* @param cardNumber The new card number.
*/
public void setCardNumber(final CardNumber cardNumber) {
this.cardNumber = cardNumber;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return cardNumber + (new Formatter()).format(" exp: %1$tm/%1$ty", expiry).toString();
}
}
往来账户:
public class CurrentAccount extends Account {
private BankCard debitCard;
/**
* Get the debit card for this account.
*
* @return The debit card.
*/
public BankCard getDebitCard() {
return debitCard;
}
/**
* Set the debit card for this account.
*
* @param debitCard The debit card. The card type must be
* {@link CardType#DebitCard}.
*/
public void setDebitCard(final BankCard debitCard) {
if (debitCard.getKind() != BankCard.CardType.DebitCard) {
throw new IllegalArgumentException("The given card is not a debit card");
}
this.debitCard = debitCard;
}
/**
* Get the credit card for this account.
*
* @return The credit card.
*/
public BankCard getCreditCard() {
return creditCard;
}
/**
* Set the credit card for this account.
*
* @param creditCard The credit card. The card type must be
* {@link CardType#CreditCard}.
*/
public void setCreditCard(final BankCard creditCard) {
if (creditCard.getKind() != BankCard.CardType.CreditCard) {
throw new IllegalArgumentException("The given card is not a credit card");
}
this.creditCard = creditCard;
}
private BankCard creditCard;
private BigDecimal overdraftLimit;
/**
* Create a new account with initial zero balance.
*
* @param customer The customer owning the account. This account will be
* added to the customer automatically.
* @param accountNumber The account number.
* @param overdraftLimit The overdraft limit on the account.
*/
public CurrentAccount(final Customer customer, final AccountNumber accountNumber, final BigDecimal overdraftLimit) {
super(customer, accountNumber);
this.overdraftLimit = overdraftLimit;
setDebitCard(new BankCard(BankCard.CardType.DebitCard));
setCreditCard(new BankCard(BankCard.CardType.CreditCard));
}
/**
* Create a new account with initialized with a given balance.
*
* @param customer The customer owning the account. This account will be
* added to the customer automatically.
* @param accountNumber The account number.
* @param balance The initial balance of the account.
* @param overdraftLimit The overdraft limit on the account.
*/
public CurrentAccount(final Customer customer, final AccountNumber accountNumber, final BigDecimal balance, final BigDecimal overdraftLimit) {
super(customer, accountNumber, balance);
this.overdraftLimit = overdraftLimit;
setDebitCard(new BankCard(BankCard.CardType.DebitCard));
setCreditCard(new BankCard(BankCard.CardType.CreditCard));
}
/**
* Get the overdraft limit for the account.
*
* @see prog2.as1.Account#getOverdraftLimit()
*/
@Override
public BigDecimal getOverdraftLimit() {
return overdraftLimit;
}
/**
* Set the overdraft limit of the account.
*
* @param overdraftLimit The new limit.
*/
public void setOverdraftLimit(final BigDecimal overdraftLimit) {
this.overdraftLimit = overdraftLimit;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
String s = super.toString();
StringBuilder result = new StringBuilder(s.length() + 50);
result.append(s.substring(0, s.length() - 1)).append(", debitcard: [").append(debitCard).append(']');
result.append(", creditcard: [").append(creditCard).append("])");
return result.toString();
}
/**
* {@inheritDoc}
*/
@Override
public String getAccountName() {
return "Current Account";
}
}
银行公用:
package prog2.as1.test;
import java.math.BigDecimal;
import java.util.GregorianCalendar;
import org.junit.Before;
import prog2.as1.AccountNumber;
import prog2.as1.Address;
import prog2.as1.Bank;
import prog2.as1.Branch;
import prog2.as1.CurrentAccount;
import prog2.as1.Customer;
import prog2.as1.EmploymentStatus;
import prog2.as1.HighInterestSavingsAccount;
import prog2.as1.ISASavingsAccount;
import prog2.as1.PhoneNumber;
import prog2.as1.StandardSavingsAccount;
@SuppressWarnings("javadoc")
public class BankCommon {
protected Bank bank;
protected Branch branch1;
protected Branch branch2;
protected Branch branch3;
protected Customer customer1;
protected Customer customer2;
protected Customer manager3;
protected Customer manager2;
protected Customer manager1;
public BankCommon() {
super();
}
@Before
public void setUp() throws Exception {
manager1 = new Customer("Gordon", "Gecko", new GregorianCalendar(1951, 5, 23), EmploymentStatus.Permanent);
branch1 = new Branch("Winton", new Address("6", "Bournemouth Road", "BH4 1AA", "Bournemouth", "Dorset", Address.UK), new PhoneNumber("01202 123456"), manager1);
manager2 = new Customer("Sarah", "Jane", new GregorianCalendar(1952, 2, 29), EmploymentStatus.SelfEmployed);
branch2 = new Branch("Poole", new Address("12", "Swanage Road", "BH12 5XY", "Poole", "Dorset", Address.UK), new PhoneNumber("01202 123457"), manager2);
manager3 = new Customer("John", "Person", new GregorianCalendar(1961, 11, 5), EmploymentStatus.Temporary);
branch3 = new Branch("Bournemouth", new Address("6", "Winton Road", "BH1 1AA", "Bournemouth", "Dorset", Address.UK), new PhoneNumber("01202 123458"), manager3);
bank = new Bank("Northern Rock", branch1, branch2, branch3);
customer1 = new Customer("John", "Doe", new GregorianCalendar(1970, 1, 1), EmploymentStatus.Unemployed);
customer1.addAccount(new CurrentAccount(customer1, AccountNumber.getNextAccountNumber(), BigDecimal.valueOf(100), BigDecimal.valueOf(500)));
customer1.addAccount(new ISASavingsAccount(customer1, AccountNumber.getNextAccountNumber(), BigDecimal.valueOf(1000)));
branch1.getCustomers().add(customer1);
manager3.addAccount(new CurrentAccount(manager3, AccountNumber.getNextAccountNumber(), BigDecimal.valueOf(10000)));
manager3.addAccount(new HighInterestSavingsAccount(manager3, AccountNumber.getNextAccountNumber(), BigDecimal.valueOf(20000)));
branch3.getCustomers().add(manager3);
customer2 = new Customer("Jane", "Doe", new GregorianCalendar(1971, 1, 1), EmploymentStatus.Temporary);
customer2.addAccount(new CurrentAccount(customer2, AccountNumber.getNextAccountNumber(), BigDecimal.valueOf(100), BigDecimal.valueOf(600)));
customer2.addAccount(new HighInterestSavingsAccount(customer2, AccountNumber.getNextAccountNumber(), BigDecimal.valueOf(1000)));
branch1.getCustomers().add(customer2);
manager2.addAccount(new CurrentAccount(manager2, AccountNumber.getNextAccountNumber(), BigDecimal.valueOf(200)));
manager2.addAccount(new ISASavingsAccount(manager2, AccountNumber.getNextAccountNumber(), BigDecimal.valueOf(6000)));
branch2.getCustomers().add(manager2);
manager1.addAccount(new CurrentAccount(manager1, AccountNumber.getNextAccountNumber(), BigDecimal.valueOf(500)));
manager1.addAccount(new StandardSavingsAccount(manager1, AccountNumber.getNextAccountNumber(), BigDecimal.valueOf(5000)));
branch1.getCustomers().add(manager1);
}
}