diff --git a/.gitignore b/.gitignore
index 7f577e8..e947382 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,10 @@
-/.project
-/.settings
-/src
-/.idea
-/*.iml
+.project
+.settings
+target
+.classpath
+.idea
+*.iml
+.gradle
+build
+dependency-reduced-pom.xml
+/src
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 5a8b212..635783c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,6 +12,7 @@
spring3-jmx-example
spring3-rmi-example
spring3-rmi-httpinvoker-example
- spring-boot-example
+ spring-boot-example
+ spring3-testng-example
\ No newline at end of file
diff --git a/spring-boot-example/.gitignore b/spring-boot-example/.gitignore
deleted file mode 100644
index 16096af..0000000
--- a/spring-boot-example/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/spring-boot-example.iml
-/target
-/*.iml
diff --git a/spring3-helloworld-example/.gitignore b/spring3-helloworld-example/.gitignore
deleted file mode 100644
index aab63f4..0000000
--- a/spring3-helloworld-example/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/.project
-/.settings
-/target
-/.classpath
-/*.iml
diff --git a/spring3-javaconfig-example/.gitignore b/spring3-javaconfig-example/.gitignore
deleted file mode 100644
index aab63f4..0000000
--- a/spring3-javaconfig-example/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/.project
-/.settings
-/target
-/.classpath
-/*.iml
diff --git a/spring3-javaconfig-import-example/.gitignore b/spring3-javaconfig-import-example/.gitignore
deleted file mode 100644
index aab63f4..0000000
--- a/spring3-javaconfig-import-example/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/.project
-/.settings
-/target
-/.classpath
-/*.iml
diff --git a/spring3-jmx-example/.gitignore b/spring3-jmx-example/.gitignore
deleted file mode 100644
index 9cc88fe..0000000
--- a/spring3-jmx-example/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/target
-/.classpath
-/.project
-/.settings
-/*.iml
diff --git a/spring3-mvc-simple/.gitignore b/spring3-mvc-simple/.gitignore
deleted file mode 100644
index 82e4348..0000000
--- a/spring3-mvc-simple/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-/target
-/.classpath
-/.project
-/.gradle
-/.settings
-/build
-/*.iml
diff --git a/spring3-rmi-example/.gitignore b/spring3-rmi-example/.gitignore
deleted file mode 100644
index aab63f4..0000000
--- a/spring3-rmi-example/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/.project
-/.settings
-/target
-/.classpath
-/*.iml
diff --git a/spring3-rmi-httpinvoker-example/.gitignore b/spring3-rmi-httpinvoker-example/.gitignore
deleted file mode 100644
index 338b6a8..0000000
--- a/spring3-rmi-httpinvoker-example/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-/target/
-/dependency-reduced-pom.xml
-/.settings
-/.classpath
-/.project
-/*.iml
diff --git a/spring3-testng-example/pom.xml b/spring3-testng-example/pom.xml
new file mode 100644
index 0000000..32ad358
--- /dev/null
+++ b/spring3-testng-example/pom.xml
@@ -0,0 +1,57 @@
+
+
+
+ maven-framework-project
+ net.aimeizi
+ 1.0.0
+
+ 4.0.0
+
+ spring3-testng-example
+
+
+
+ 3.1.1.RELEASE
+
+
+
+
+
+ org.springframework
+ spring-core
+ ${spring.version}
+
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+
+ org.springframework
+ spring-test
+ ${spring.version}
+
+
+
+
+ org.testng
+ testng
+ 6.4
+
+
+
+
+ log4j
+ log4j
+ 1.2.16
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/cache/service/CacheService.java b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/cache/service/CacheService.java
new file mode 100644
index 0000000..325c7dd
--- /dev/null
+++ b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/cache/service/CacheService.java
@@ -0,0 +1,33 @@
+package net.aimeizi.spring.testng.example.cache.service;
+
+import net.aimeizi.spring.testng.example.model.User;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Created by welcome on 2014/7/1 0001.
+ */
+public class CacheService implements ICacheService {
+
+ //User Map is injected...
+ private ConcurrentHashMap userMap;
+
+ /**
+ * Gets User Map
+ *
+ * @return ConcurrentHashMap User Map
+ */
+ public ConcurrentHashMap getUserMap() {
+ return userMap;
+ }
+
+ /**
+ * Sets User Map
+ *
+ * @param ConcurrentHashMap User Map
+ */
+ public void setUserMap(ConcurrentHashMap userMap) {
+ this.userMap = userMap;
+ }
+
+}
\ No newline at end of file
diff --git a/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/cache/service/ICacheService.java b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/cache/service/ICacheService.java
new file mode 100644
index 0000000..803d283
--- /dev/null
+++ b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/cache/service/ICacheService.java
@@ -0,0 +1,18 @@
+package net.aimeizi.spring.testng.example.cache.service;
+
+import net.aimeizi.spring.testng.example.model.User;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Created by welcome on 2014/7/1 0001.
+ */
+public interface ICacheService {
+
+ /**
+ * Gets User Map
+ *
+ * @return ConcurrentHashMap User Map
+ */
+ ConcurrentHashMap getUserMap();
+}
diff --git a/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/common/exceptions/NonExistentUserException.java b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/common/exceptions/NonExistentUserException.java
new file mode 100644
index 0000000..c2fe17f
--- /dev/null
+++ b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/common/exceptions/NonExistentUserException.java
@@ -0,0 +1,14 @@
+package net.aimeizi.spring.testng.example.common.exceptions;
+
+/**
+ * Created by 冯靖 on 2014/7/1 0001.
+ */
+public class NonExistentUserException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public NonExistentUserException(String message) {
+ super(message);
+ }
+
+}
diff --git a/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/model/User.java b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/model/User.java
new file mode 100644
index 0000000..7224f46
--- /dev/null
+++ b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/model/User.java
@@ -0,0 +1,111 @@
+package net.aimeizi.spring.testng.example.model;
+
+/**
+ * Created by 冯靖 on 2014/7/1 0001.
+ */
+public class User {
+
+ private String id;
+ private String name;
+ private String surname;
+
+ /**
+ * Gets User Id
+ *
+ * @return String id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Sets User Id
+ *
+ * @param String id
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Gets User Name
+ *
+ * @return String name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets User Name
+ *
+ * @param String name
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Gets User Surname
+ *
+ * @return String Surname
+ */
+ public String getSurname() {
+ return surname;
+ }
+
+ /**
+ * Sets User Surname
+ *
+ * @param String surname
+ */
+ public void setSurname(String surname) {
+ this.surname = surname;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder strBuilder = new StringBuilder();
+ strBuilder.append("Id : ").append(getId());
+ strBuilder.append(", Name : ").append(getName());
+ strBuilder.append(", Surname : ").append(getSurname());
+ return strBuilder.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((surname == null) ? 0 : surname.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ User other = (User) obj;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (surname == null) {
+ if (other.surname != null)
+ return false;
+ } else if (!surname.equals(other.surname))
+ return false;
+ return true;
+ }
+}
diff --git a/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/service/IUserService.java b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/service/IUserService.java
new file mode 100644
index 0000000..848bba9
--- /dev/null
+++ b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/service/IUserService.java
@@ -0,0 +1,51 @@
+package net.aimeizi.spring.testng.example.service;
+
+import net.aimeizi.spring.testng.example.common.exceptions.NonExistentUserException;
+import net.aimeizi.spring.testng.example.model.User;
+
+import java.util.Collection;
+
+/**
+ * Created by welcome on 2014/7/1 0001.
+ */
+public interface IUserService {
+
+ /**
+ * Adds User
+ *
+ * @param User user
+ * @return boolean whether delete operation is success or not.
+ */
+ boolean addUser(User user);
+
+ /**
+ * Deletes User
+ *
+ * @param User user
+ * @return boolean whether delete operation is success or not.
+ */
+ boolean deleteUser(User user);
+
+ /**
+ * Updates User
+ *
+ * @param User user
+ * @throws NonExistentUserException
+ */
+ void updateUser(User user) throws NonExistentUserException;
+
+ /**
+ * Gets User
+ *
+ * @param String User Id
+ * @return User
+ */
+ User getUserById(String id);
+
+ /**
+ * Gets User Collection
+ *
+ * @return List - User list
+ */
+ Collection getUsers();
+}
\ No newline at end of file
diff --git a/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/service/UserService.java b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/service/UserService.java
new file mode 100644
index 0000000..c77244f
--- /dev/null
+++ b/spring3-testng-example/src/main/java/net/aimeizi/spring/testng/example/service/UserService.java
@@ -0,0 +1,98 @@
+package net.aimeizi.spring.testng.example.service;
+
+import net.aimeizi.spring.testng.example.cache.service.ICacheService;
+import net.aimeizi.spring.testng.example.common.exceptions.NonExistentUserException;
+import net.aimeizi.spring.testng.example.model.User;
+
+import java.util.Collection;
+
+/**
+ * Created by welcome on 2014/7/1 0001.
+ */
+public class UserService implements IUserService {
+
+ //CacheService is injected...
+ private ICacheService cacheService;
+
+ /**
+ * Adds User
+ *
+ * @param User user
+ * @return boolean whether delete operation is success or not.
+ */
+ public boolean addUser(User user) {
+
+ getCacheService().getUserMap().put(user.getId(), user);
+ if(getCacheService().getUserMap().get(user.getId()).equals(user)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Deletes User
+ *
+ * @param User user
+ * @return boolean whether delete operation is success or not.
+ */
+ public boolean deleteUser(User user) {
+ User removedUser = getCacheService().getUserMap().remove(user.getId());
+ if(removedUser != null) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Updates User
+ *
+ * @param User user
+ * @throws NonExistentUserException
+ */
+ public void updateUser(User user) throws NonExistentUserException {
+ if(getCacheService().getUserMap().containsKey(user.getId())) {
+ getCacheService().getUserMap().put(user.getId(), user);
+ } else {
+ throw new NonExistentUserException("Non Existent User can not update! User : "+user);
+ }
+ }
+
+ /**
+ * Gets User
+ *
+ * @param String User Id
+ * @return User
+ */
+ public User getUserById(String id) {
+ return getCacheService().getUserMap().get(id);
+ }
+
+ /**
+ * Gets User List
+ *
+ * @return Collection - Collection of Users
+ */
+ public Collection getUsers() {
+ return (Collection) getCacheService().getUserMap().values();
+ }
+
+ /**
+ * Gets Cache Service
+ *
+ * @return ICacheService - Cache Service
+ */
+ public ICacheService getCacheService() {
+ return cacheService;
+ }
+
+ /**
+ * Sets Cache Service
+ *
+ * @param ICacheService - Cache Service
+ */
+ public void setCacheService(ICacheService cacheService) {
+ this.cacheService = cacheService;
+ }
+
+}
\ No newline at end of file
diff --git a/spring3-testng-example/src/main/java/test/UserServiceTester.java b/spring3-testng-example/src/main/java/test/UserServiceTester.java
new file mode 100644
index 0000000..1c1cf0f
--- /dev/null
+++ b/spring3-testng-example/src/main/java/test/UserServiceTester.java
@@ -0,0 +1,196 @@
+package test;
+
+import junit.framework.Assert;
+
+import net.aimeizi.spring.testng.example.common.exceptions.NonExistentUserException;
+import net.aimeizi.spring.testng.example.model.User;
+import net.aimeizi.spring.testng.example.service.IUserService;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+/**
+ * Created by welcome on 2014/7/1 0001.
+ */
+@ContextConfiguration(locations={"classpath:applicationContext.xml"})
+public class UserServiceTester extends AbstractTestNGSpringContextTests {
+
+ private static Logger logger = Logger.getLogger(UserServiceTester.class);
+
+ @Autowired
+ private IUserService userService;
+
+ private User firstUser;
+ private User secondUser;
+ private User thirdUser;
+
+ /**
+ * Creates Test Users
+ *
+ */
+ private void createUsers() {
+ firstUser = new User();
+ firstUser.setId("1");
+ firstUser.setName("Lionel");
+ firstUser.setSurname("Messi");
+
+ secondUser = new User();
+ secondUser.setId("2");
+ secondUser.setName("David");
+ secondUser.setSurname("Villa");
+
+ thirdUser = new User();
+ thirdUser.setId("3");
+ thirdUser.setName("Andres");
+ thirdUser.setSurname("Iniesta");
+ }
+
+ /**
+ * Asserts that User Properties are not null.
+ *
+ * @param user
+ */
+ private void assertNotNullUserProperties(User user) {
+ Assert.assertNotNull("User must not be null!", user);
+ Assert.assertNotNull("Id must not be null!", user.getId());
+ Assert.assertNotNull("Name must not be null!", user.getName());
+ Assert.assertNotNull("Surname must not be null!", user.getSurname());
+ }
+
+ /**
+ * The annotated method will be run before any test method belonging to the classes
+ * inside the tag is run.
+ *
+ */
+ @BeforeTest
+ public void beforeTest() {
+ logger.debug("BeforeTest method is run...");
+ }
+
+ /**
+ * The annotated method will be run before the first test method in the current class
+ * is invoked.
+ *
+ */
+ @BeforeClass
+ public void beforeClass() {
+ logger.debug("BeforeClass method is run...");
+ createUsers();
+ }
+
+ /**
+ * The annotated method will be run before each test method.
+ *
+ */
+ @BeforeMethod
+ public void beforeMethod() {
+ logger.debug("BeforeMethod method is run...");
+ }
+
+ /**
+ * Tests the process of adding user
+ *
+ */
+ @Test
+ public void addUser() {
+ assertNotNullUserProperties(firstUser);
+ Assert.assertTrue("User can not be added! User : " + firstUser, getUserService().addUser(firstUser));
+ }
+
+ /**
+ * Tests the process of querying user
+ *
+ */
+ @Test
+ public void getUserById() {
+ User tempUser = getUserService().getUserById(firstUser.getId());
+ assertNotNullUserProperties(tempUser);
+ Assert.assertEquals("Id is wrong!", "1", tempUser.getId());
+ Assert.assertEquals("Name is wrong!", "Lionel", tempUser.getName());
+ Assert.assertEquals("Surname is wrong!", "Messi", tempUser.getSurname());
+ }
+
+ /**
+ * Tests the process of deleting user
+ *
+ */
+ @Test
+ public void deleteUser() {
+ assertNotNullUserProperties(secondUser);
+ Assert.assertTrue("User can not be added! User : " + secondUser, getUserService().addUser(secondUser));
+ Assert.assertTrue("User can not be deleted! User : " + secondUser, getUserService().deleteUser(secondUser));
+ }
+
+ /**
+ * Tests the process of updating user
+ * @throws NonExistentUserException
+ *
+ */
+ @Test(expectedExceptions = NonExistentUserException.class)
+ public void updateUser() throws NonExistentUserException {
+ getUserService().updateUser(thirdUser);
+ }
+
+ /**
+ * Test user count
+ *
+ */
+ @Test
+ public void getUserCount() {
+ Assert.assertEquals(1, getUserService().getUsers().size());
+ }
+
+ /**
+ * The annotated method will be run after all the test methods in the current class have been run.
+ *
+ */
+ @AfterClass
+ public void afterClass() {
+ logger.debug("AfterClass method is run...");
+ }
+
+ /**
+ * The annotated method will be run after all the test methods belonging to the classes inside the tag have run.
+ *
+ */
+ @AfterTest
+ public void afterTest() {
+ logger.debug("AfterTest method is run...");
+ }
+
+ /**
+ * The annotated method will be run after each test method.
+ *
+ */
+ @AfterMethod
+ public void afterMethod() {
+ logger.debug("AfterMethod method is run...");
+ }
+
+ /**
+ * Gets User Service
+ *
+ * @return IUserService User Service
+ */
+ public IUserService getUserService() {
+ return userService;
+ }
+
+ /**
+ * Sets User Service
+ *
+ * @param userService
+ */
+ public void setUserService(IUserService userService) {
+ this.userService = userService;
+ }
+
+}
diff --git a/spring3-testng-example/src/main/resources/applicationContext.xml b/spring3-testng-example/src/main/resources/applicationContext.xml
new file mode 100644
index 0000000..4d8b5c3
--- /dev/null
+++ b/spring3-testng-example/src/main/resources/applicationContext.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file