本文從一個(gè)例子出發(fā),根據(jù)TDD(測(cè)試驅(qū)動(dòng)開(kāi)發(fā))要求,進(jìn)行開(kāi)發(fā)。只是用于演示如何使用Spring2.5提供的基于Annonation方式的IOC實(shí)現(xiàn),進(jìn)行TDD開(kāi)發(fā)。
首先我們來(lái)看一下這個(gè)例子的要求:
開(kāi)發(fā)一個(gè)購(gòu)物車對(duì)象,可以添加商品,刪除商品,查詢已購(gòu)商口,結(jié)賬功能。
第一步,先來(lái)完成添加商品功能,下面就按TDD開(kāi)發(fā)要求,先編寫(xiě)單元測(cè)試:
下面是增對(duì)該功能,編寫(xiě)的測(cè)試代碼
1 /**
2 * @author xmatthew
3 *
4 */
5 @RunWith(SpringJUnit4ClassRunner.class)
6 @ContextConfiguration(locations = {"classpath:/applicationContext.xml"})
7 @TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
8 public class CartTest {
9
10 @Autowired
11 private SuperStore superStore;
12
13 @Test
14 public void addCommodity() {
15
16 Cart cart = new Cart();
17 Commodity commodity = superStore.getCommodity("1"/*電腦桌*/);
18 cart.addCommodity(commodity);
19
20 Assert.assertEquals(1, cart.size());
21 Assert.assertTrue(cart.contains(commodity));
22
23 }
24 }
2 * @author xmatthew
3 *
4 */
5 @RunWith(SpringJUnit4ClassRunner.class)
6 @ContextConfiguration(locations = {"classpath:/applicationContext.xml"})
7 @TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
8 public class CartTest {
9
10 @Autowired
11 private SuperStore superStore;
12
13 @Test
14 public void addCommodity() {
15
16 Cart cart = new Cart();
17 Commodity commodity = superStore.getCommodity("1"/*電腦桌*/);
18 cart.addCommodity(commodity);
19
20 Assert.assertEquals(1, cart.size());
21 Assert.assertTrue(cart.contains(commodity));
22
23 }
24 }
當(dāng)然這個(gè)單元測(cè)試不能通過(guò)(無(wú)法編譯).接下來(lái)就是編寫(xiě)代碼,讓單元測(cè)試能順利通過(guò)
添加 applicationContext.xml文件
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
7 http://www.springframework.org/schema/context
8 http://www.springframework.org/schema/context/spring-context-2.5.xsd">
9
10
11 <context:component-scan base-package="com.xmatthew.spring.tdd"/>
12 <context:annotation-config/>
13
14
15 </beans>
16
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
7 http://www.springframework.org/schema/context
8 http://www.springframework.org/schema/context/spring-context-2.5.xsd">
9
10
11 <context:component-scan base-package="com.xmatthew.spring.tdd"/>
12 <context:annotation-config/>
13
14
15 </beans>
16
Commodity.java
1 /**
2 * @author xmatthew
3 *
4 */
5 public class Commodity {
6
7 private String id;
8 private String name;
9 private BigDecimal price;
10
11 /* (non-Javadoc)
12 * @see java.lang.Object#equals(java.lang.Object)
13 */
14 @Override
15 public boolean equals(final Object other) {
16 if (!(other instanceof Commodity))
17 return false;
18 Commodity castOther = (Commodity) other;
19 return new EqualsBuilder().append(id, castOther.id).append(name,
20 castOther.name).append(price, castOther.price).isEquals();
21 }
22
23 /* (non-Javadoc)
24 * @see java.lang.Object#hashCode()
25 */
26 @Override
27 public int hashCode() {
28 return new HashCodeBuilder().append(id).append(name).append(price)
29 .toHashCode();
30 }
31
32 public Commodity(String id, String name, BigDecimal price) {
33 super();
34 this.id = id;
35 this.name = name;
36 this.price = price;
37 }
38
39 public String getId() {
40 return id;
41 }
42
43 public void setId(String id) {
44 this.id = id;
45 }
46
47 public String getName() {
48 return name;
49 }
50
51 public void setName(String name) {
52 this.name = name;
53 }
54
55 public BigDecimal getPrice() {
56 return price;
57 }
58
59 public void setPrice(BigDecimal price) {
60 this.price = price;
61 }
62
63
64 }
65
2 * @author xmatthew
3 *
4 */
5 public class Commodity {
6
7 private String id;
8 private String name;
9 private BigDecimal price;
10
11 /* (non-Javadoc)
12 * @see java.lang.Object#equals(java.lang.Object)
13 */
14 @Override
15 public boolean equals(final Object other) {
16 if (!(other instanceof Commodity))
17 return false;
18 Commodity castOther = (Commodity) other;
19 return new EqualsBuilder().append(id, castOther.id).append(name,
20 castOther.name).append(price, castOther.price).isEquals();
21 }
22
23 /* (non-Javadoc)
24 * @see java.lang.Object#hashCode()
25 */
26 @Override
27 public int hashCode() {
28 return new HashCodeBuilder().append(id).append(name).append(price)
29 .toHashCode();
30 }
31
32 public Commodity(String id, String name, BigDecimal price) {
33 super();
34 this.id = id;
35 this.name = name;
36 this.price = price;
37 }
38
39 public String getId() {
40 return id;
41 }
42
43 public void setId(String id) {
44 this.id = id;
45 }
46
47 public String getName() {
48 return name;
49 }
50
51 public void setName(String name) {
52 this.name = name;
53 }
54
55 public BigDecimal getPrice() {
56 return price;
57 }
58
59 public void setPrice(BigDecimal price) {
60 this.price = price;
61 }
62
63
64 }
65
SuperStore.java
1 /**
2 * @author xmatthew
3 *
4 */
5 public interface SuperStore {
6
7
8 Commodity getCommodity(String id);
9 }
2 * @author xmatthew
3 *
4 */
5 public interface SuperStore {
6
7
8 Commodity getCommodity(String id);
9 }
Cart.java
1 /**
2 * @author xmatthew
3 *
4 */
5 public class Cart {
6
7 List<Commodity> commodities = new LinkedList<Commodity>();
8
9 public void addCommodity(Commodity commodity) {
10 commodities.add(commodity);
11
12 }
13
14 public boolean contains(Commodity commodity) {
15 // TODO Auto-generated method stub
16 return commodities.contains(commodity);
17 }
18
19 public int size() {
20 // TODO Auto-generated method stub
21 return commodities.size();
22 }
23
24 }
2 * @author xmatthew
3 *
4 */
5 public class Cart {
6
7 List<Commodity> commodities = new LinkedList<Commodity>();
8
9 public void addCommodity(Commodity commodity) {
10 commodities.add(commodity);
11
12 }
13
14 public boolean contains(Commodity commodity) {
15 // TODO Auto-generated method stub
16 return commodities.contains(commodity);
17 }
18
19 public int size() {
20 // TODO Auto-generated method stub
21 return commodities.size();
22 }
23
24 }
1 /**
2 * @author xmatthew
3 *
4 */
5 @Service
6 public class WalMart implements SuperStore {
7
8 private Map<String, Commodity> commodities;
9
10 public WalMart() {
11 super();
12 commodities = new HashMap<String, Commodity>(3);
13 commodities.put("1", new Commodity("1", "電腦桌", new BigDecimal(1288)));
14 commodities.put("2", new Commodity("2", "電腦椅", new BigDecimal(588)));
15 commodities.put("3", new Commodity("1", "電腦包", new BigDecimal(368)));
16 }
17
18 public Commodity getCommodity(String id) {
19 Assert.hasText(id, "id is null");
20 return commodities.get(id);
21 }
22
23 }
2 * @author xmatthew
3 *
4 */
5 @Service
6 public class WalMart implements SuperStore {
7
8 private Map<String, Commodity> commodities;
9
10 public WalMart() {
11 super();
12 commodities = new HashMap<String, Commodity>(3);
13 commodities.put("1", new Commodity("1", "電腦桌", new BigDecimal(1288)));
14 commodities.put("2", new Commodity("2", "電腦椅", new BigDecimal(588)));
15 commodities.put("3", new Commodity("1", "電腦包", new BigDecimal(368)));
16 }
17
18 public Commodity getCommodity(String id) {
19 Assert.hasText(id, "id is null");
20 return commodities.get(id);
21 }
22
23 }
增加上面代碼,再運(yùn)行單元測(cè)試,測(cè)試通過(guò)。TDD的基本開(kāi)方法就類似下面幾個(gè)步驟:
* 編寫(xiě)測(cè)試代碼
* 運(yùn)行測(cè)試
* 完善(重構(gòu))代碼
* 再測(cè)試
* 最終測(cè)試通過(guò)
示例比較簡(jiǎn)單,只是為了演示基于Spring2.5版本上如何進(jìn)行TDD開(kāi)發(fā)。
我看到在Spring2.5進(jìn)行代碼的測(cè)試變得非常簡(jiǎn)單
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/applicationContext.xml"})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
上面的代碼,就可實(shí)現(xiàn)自動(dòng)加載Spring context@ContextConfiguration(locations = {"classpath:/applicationContext.xml"})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
@Autowired
private SuperStore superStore;
使用Spring的Configuration功能,自動(dòng)實(shí)現(xiàn)依賴注入。感謝Spring Configuration項(xiàng)目,讓IOC實(shí)現(xiàn)更簡(jiǎn)單,方便。private SuperStore superStore;
當(dāng)然不得不提的就是Junit4 測(cè)試框架給是給我們編寫(xiě)單元簡(jiǎn)化了很多。
本文示例代碼下載
Good Luck!
Yours Matthew!
posted on 2008-11-05 19:40 x.matthew 閱讀(1911) 評(píng)論(2) 編輯 收藏 所屬分類: Spring|Hibernate|Other framework