-5

当我运行 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);

}

}
4

1 回答 1

2

显然这是因为生成的 CardNumber 字符串长于或短于 16 个字符:

if (toString().length() != 16) {
    throw new NumberFormatException("The string \"" + origString + "\" does not have the proper length of a card number");
}
于 2013-11-10T19:41:53.370 回答