我正在研究Spring Core认证,并且我对在Spring中使用Junit有以下疑问。
我有一个示例,为我提供了以下RewardNetworkTests类
package rewards;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import common.money.MonetaryAmount;
/**
* A system test that verifies the components of the RewardNetwork application
* work together to reward for dining successfully. Uses Spring to bootstrap the
* application for use in a test environment.
*/
public class RewardNetworkTests {
/**
* The object being tested.
*/
private RewardNetwork rewardNetwork;
/**
* Need this to enable clean shutdown at the end of the application
*/
private AbstractApplicationContext context;
@Before
public void setUp() {
// Create the test configuration for the application from one file
context = new AnnotationConfigApplicationContext(
TestInfrastructureConfig.class);
// Get the bean to use to invoke the application
rewardNetwork = context.getBean(RewardNetwork.class);
}
@After
public void tearDown() throws Exception {
// simulate the Spring bean destruction lifecycle:
if (context != null)
context.close();
}
@Test
public void testRewardForDining() {
// create a new dining of 100.00 charged to credit card
// '1234123412341234' by merchant '123457890' as test input
Dining dining = Dining.createDining("100.00", "1234123412341234",
"1234567890");
// call the 'rewardNetwork' to test its rewardAccountFor(Dining) method
RewardConfirmation confirmation = rewardNetwork
.rewardAccountFor(dining);
// assert the expected reward confirmation results
assertNotNull(confirmation);
assertNotNull(confirmation.getConfirmationNumber());
// assert an account contribution was made
AccountContribution contribution = confirmation
.getAccountContribution();
assertNotNull(contribution);
// the contribution account number should be '123456789'
assertEquals("123456789", contribution.getAccountNumber());
// the total contribution amount should be 8.00 (8% of 100.00)
assertEquals(MonetaryAmount.valueOf("8.00"), contribution.getAmount());
// the total contribution amount should have been split into 2
// distributions
assertEquals(2, contribution.getDistributions().size());
// each distribution should be 4.00 (as both have a 50% allocation)
assertEquals(MonetaryAmount.valueOf("4.00"), contribution
.getDistribution("Annabelle").getAmount());
assertEquals(MonetaryAmount.valueOf("4.00"), contribution
.getDistribution("Corgan").getAmount());
}
}
因此,此测试类包含setUp()方法,该方法从TestInfrastructureConfig.class配置类开始创建上下文:
@Before
public void setUp() {
// Create the test configuration for the application from one file
context = new AnnotationConfigApplicationContext(
TestInfrastructureConfig.class);
// Get the bean to use to invoke the application
rewardNetwork = context.getBean(RewardNetwork.class);
}
这是TestInfrastructureConfig.class配置类的内容:
一揽子奖励;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.context.annotation.Import;
导入config.RewardsConfig;
@Configuration
@Import({
TestInfrastructureDevConfig.class,
TestInfrastructureProductionConfig.class,
RewardsConfig.class })
public class TestInfrastructureConfig {
public LoggingBeanPostProcessor loggingBean(){
return new LoggingBeanPostProcessor();
}
}
因此,在本教程中,它告诉我,如果我删除setUp()方法,并且在执行此操作后尝试执行测试,我会得到一个红色条,因为rewardNetwork字段为null
好的,我认为这可能取决于以下事实:删除setUp()方法时,我不是从TestInfrastructureConfig.class配置类中获取上下文,而后者又导入了RewardsConfig.class配置类,该组件在该类中声明了组件扫描。用于:
@ComponentScan("rewards")
因此,该应用程序不能使用在奖励包的子包中声明的RewardNetworkImpl类(实现RewardNetwork接口),并将其标注为@Service:
@Service("rewardNetwork")
public class RewardNetworkImpl implements RewardNetwork {
...................................
...................................
...................................
}
好的,我认为这很清楚(还是我错过了什么?)
我的怀疑是。回到以前的测试方法:
@Test
public void testRewardForDining() {
// create a new dining of 100.00 charged to credit card
// '1234123412341234' by merchant '123457890' as test input
Dining dining = Dining.createDining("100.00", "1234123412341234",
"1234567890");
// call the 'rewardNetwork' to test its rewardAccountFor(Dining) method
RewardConfirmation confirmation = rewardNetwork
.rewardAccountFor(dining);
...................................................
...................................................
...................................................
}
可以看出,在未建立的rewardNetwork对象上调用rewardAccountFor()方法时会引发异常,但是为什么使用调试器在Dinning dinning对象上调用createDining()方法呢?
为什么实例化该对象没有问题?
这是Dinning类代码:
public class Dining {
private MonetaryAmount amount;
private String creditCardNumber;
private String merchantNumber;
private SimpleDate date;
/**
* Creates a new dining, reflecting an amount that was charged to a card by a merchant on the date specified.
* @param amount the total amount of the dining bill
* @param creditCardNumber the number of the credit card used to pay for the dining bill
* @param merchantNumber the merchant number of the restaurant where the dining occurred
* @param date the date of the dining event
*/
public Dining(MonetaryAmount amount, String creditCardNumber, String merchantNumber, SimpleDate date) {
this.amount = amount;
this.creditCardNumber = creditCardNumber;
this.merchantNumber = merchantNumber;
this.date = date;
}
/**
* Creates a new dining, reflecting an amount that was charged to a credit card by a merchant on today's date. A
* convenient static factory method.
* @param amount the total amount of the dining bill as a string
* @param creditCardNumber the number of the credit card used to pay for the dining bill
* @param merchantNumber the merchant number of the restaurant where the dining occurred
* @return the dining event
*/
public static Dining createDining(String amount, String creditCardNumber, String merchantNumber) {
return new Dining(MonetaryAmount.valueOf(amount), creditCardNumber, merchantNumber, SimpleDate.today());
}
/**
* Creates a new dining, reflecting an amount that was charged to a credit card by a merchant on the date specified.
* A convenient static factory method.
* @param amount the total amount of the dining bill as a string
* @param creditCardNumber the number of the credit card used to pay for the dining bill
* @param merchantNumber the merchant number of the restaurant where the dining occurred
* @param month the month of the dining event
* @param day the day of the dining event
* @param year the year of the dining event
* @return the dining event
*/
public static Dining createDining(String amount, String creditCardNumber, String merchantNumber, int month,
int day, int year) {
return new Dining(MonetaryAmount.valueOf(amount), creditCardNumber, merchantNumber, new SimpleDate(month, day,
year));
}
/**
* Returns the amount of this dining--the total amount of the bill that was charged to the credit card.
*/
public MonetaryAmount getAmount() {
return amount;
}
/**
* Returns the number of the credit card used to pay for this dining. For this dining to be eligible for reward,
* this credit card number should be associated with a valid account in the reward network.
*/
public String getCreditCardNumber() {
return creditCardNumber;
}
/**
* Returns the merchant number of the restaurant where this dining occurred. For this dining to be eligible for
* reward, this merchant number should be associated with a valid restaurant in the reward network.
*/
public String getMerchantNumber() {
return merchantNumber;
}
/**
* Returns the date this dining occurred on.
*/
public SimpleDate getDate() {
return date;
}
public boolean equals(Object o) {
if (!(o instanceof Dining)) {
return false;
}
Dining other = (Dining) o;
// value objects are equal if their attributes are equal
return amount.equals(other.amount) && creditCardNumber.equals(other.creditCardNumber)
&& merchantNumber.equals(other.merchantNumber) && date.equals(other.date);
}
public int hashCode() {
return amount.hashCode() + creditCardNumber.hashCode() + merchantNumber.hashCode() + date.hashCode();
}
public String toString() {
return "Dining of " + amount + " charged to '" + creditCardNumber + "' by '" + merchantNumber + "' on " + date;
}
}
特纳克斯
最佳答案
Dining
似乎是一个类,而createDining
似乎是一个static
方法。无需创建Dining
对象即可调用这种方法。
这等效于
System.currentTimeMillis();
Spring不参与
static
方法调用。