编程填空:学生信息处理程序_项目学生:业务层
編程填空:學生信息處理程序
這是Project Student的一部分。 其他職位包括帶有Jersey的Webservice Client,帶有Jersey的 Webservice Server和帶有Spring Data的Persistence 。
RESTful Webapp洋蔥的第三層是業(yè)務層。 這就是應用程序的精髓所在–編寫良好的持久性和Web服務層受到約束,但是任何事情都在業(yè)務層中進行。
此時我們僅實現(xiàn)CRUD方法,因此這些方法非常簡單。
設計決策
Spring Data –我們將使用Spring Data作為持久層,因此我們需要牢記指定持久層接口。 正如我們將在下一個博客中看到的那樣,這大大簡化了我們的生活。
局限性
DataAccessException –不會嘗試根據(jù)我們收到的DataAccessException的類型拋出不同的異常。 稍后這將很重要-我們應該以不同于丟失數(shù)據(jù)庫連接的方式對待約束違反。
服務介面
首先提醒我們在上一篇文章中確定的服務接口。
public interface CourseService {List<Course> findAllCourses();Course findCourseById(Integer id);Course findCourseByUuid(String uuid);Course createCourse(String name);Course updateCourse(Course course, String name);void deleteCourse(String uuid); }服務實施
由于服務是基本的CRUD操作,因此該服務的實施速度很快。 我們唯一關心的是數(shù)據(jù)庫是否存在問題(Spring中的DataAccessException)或找不到期望值。 我們需要在前者的API中添加新的例外,而后者的API中已經(jīng)有例外。
public class CourseServiceImpl implements CourseService {private static final Logger log = LoggerFactory.getLogger(CourseServiceImpl.class);@Resourceprivate CourseRepository courseRepository;/*** Default constructor*/public CourseServiceImpl() {}/*** Constructor used in unit tests*/CourseServiceImpl(CourseRepository courseRepository) {this.courseRepository = courseRepository;}/*** @see com.invariantproperties.sandbox.student.business.CourseService#* findAllCourses()*/@Transactional(readOnly = true)@Overridepublic List<Course> findAllCourses() {List<Course> courses = null;try {courses = courseRepository.findAll();} catch (DataAccessException e) {if (!(e instanceof UnitTestException)) {log.info("error loading list of courses: " + e.getMessage(), e);}throw new PersistenceException("unable to get list of courses.", e);}return courses;}/*** @see com.invariantproperties.sandbox.student.business.CourseService#* findCourseById(java.lang.Integer)*/@Transactional(readOnly = true)@Overridepublic Course findCourseById(Integer id) {Course course = null;try {course = courseRepository.findOne(id);} catch (DataAccessException e) {if (!(e instanceof UnitTestException)) {log.info("internal error retrieving course: " + id, e);}throw new PersistenceException("unable to find course by id", e, id);}if (course == null) {throw new ObjectNotFoundException(id);}return course;}/*** @see com.invariantproperties.sandbox.student.business.CourseService#* findCourseByUuid(java.lang.String)*/@Transactional(readOnly = true)@Overridepublic Course findCourseByUuid(String uuid) {Course course = null;try {course = courseRepository.findCourseByUuid(uuid);} catch (DataAccessException e) {if (!(e instanceof UnitTestException)) {log.info("internal error retrieving course: " + uuid, e);}throw new PersistenceException("unable to find course by uuid", e,uuid);}if (course == null) {throw new ObjectNotFoundException(uuid);}return course;}/*** @see com.invariantproperties.sandbox.student.business.CourseService#* createCourse(java.lang.String)*/@Transactional@Overridepublic Course createCourse(String name) {final Course course = new Course();course.setName(name);Course actual = null;try {actual = courseRepository.saveAndFlush(course);} catch (DataAccessException e) {if (!(e instanceof UnitTestException)) {log.info("internal error retrieving course: " + name, e);}throw new PersistenceException("unable to create course", e);}return actual;}/*** @see com.invariantproperties.sandbox.course.persistence.CourseService#* updateCourse(com.invariantproperties.sandbox.course.domain.Course,* java.lang.String)*/@Transactional@Overridepublic Course updateCourse(Course course, String name) {Course updated = null;try {final Course actual = courseRepository.findCourseByUuid(course.getUuid());if (actual == null) {log.debug("did not find course: " + course.getUuid());throw new ObjectNotFoundException(course.getUuid());}actual.setName(name);updated = courseRepository.saveAndFlush(actual);course.setName(name);} catch (DataAccessException e) {if (!(e instanceof UnitTestException)) {log.info("internal error deleting course: " + course.getUuid(),e);}throw new PersistenceException("unable to delete course", e,course.getUuid());}return updated;}/*** @see com.invariantproperties.sandbox.student.business.CourseService#* deleteCourse(java.lang.String)*/@Transactional@Overridepublic void deleteCourse(String uuid) {Course course = null;try {course = courseRepository.findCourseByUuid(uuid);if (course == null) {log.debug("did not find course: " + uuid);throw new ObjectNotFoundException(uuid);}courseRepository.delete(course);} catch (DataAccessException e) {if (!(e instanceof UnitTestException)) {log.info("internal error deleting course: " + uuid, e);}throw new PersistenceException("unable to delete course", e, uuid);}} }該實現(xiàn)告訴我們持久層所需的接口。
持久層接口
我們將在持久層中使用Spring Data,并且DAO接口與Spring Data存儲庫相同。 我們只需要一種非標準方法。
public class CourseServiceImplTest {@Testpublic void testFindAllCourses() {final List<Course> expected = Collections.emptyList();final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findAll()).thenReturn(expected);final CourseService service = new CourseServiceImpl(repository);final List<Course> actual = service.findAllCourses();assertEquals(expected, actual);}@Test(expected = PersistenceException.class)public void testFindAllCoursesError() {final List<Course> expected = Collections.emptyList();final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findAll()).thenThrow(new UnitTestException());final CourseService service = new CourseServiceImpl(repository);final List<Course> actual = service.findAllCourses();assertEquals(expected, actual);}@Testpublic void testFindCourseById() {final Course expected = new Course();expected.setId(1);final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findOne(any(Integer.class))).thenReturn(expected);final CourseService service = new CourseServiceImpl(repository);final Course actual = service.findCourseById(expected.getId());assertEquals(expected, actual);}@Test(expected = ObjectNotFoundException.class)public void testFindCourseByIdMissing() {final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findOne(any(Integer.class))).thenReturn(null);final CourseService service = new CourseServiceImpl(repository);service.findCourseById(1);}@Test(expected = PersistenceException.class)public void testFindCourseByIdError() {final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findOne(any(Integer.class))).thenThrow(new UnitTestException());final CourseService service = new CourseServiceImpl(repository);service.findCourseById(1);}@Testpublic void testFindCourseByUuid() {final Course expected = new Course();expected.setUuid("[uuid]");final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findCourseByUuid(any(String.class))).thenReturn(expected);final CourseService service = new CourseServiceImpl(repository);final Course actual = service.findCourseByUuid(expected.getUuid());assertEquals(expected, actual);}@Test(expected = ObjectNotFoundException.class)public void testFindCourseByUuidMissing() {final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findCourseByUuid(any(String.class))).thenReturn(null);final CourseService service = new CourseServiceImpl(repository);service.findCourseByUuid("[uuid]");}@Test(expected = PersistenceException.class)public void testFindCourseByUuidError() {final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findCourseByUuid(any(String.class))).thenThrow(new UnitTestException());final CourseService service = new CourseServiceImpl(repository);service.findCourseByUuid("[uuid]");}@Testpublic void testCreateCourse() {final Course expected = new Course();expected.setName("name");expected.setUuid("[uuid]");final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.saveAndFlush(any(Course.class))).thenReturn(expected);final CourseService service = new CourseServiceImpl(repository);final Course actual = service.createCourse(expected.getName());assertEquals(expected, actual);}@Test(expected = PersistenceException.class)public void testCreateCourseError() {final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.saveAndFlush(any(Course.class))).thenThrow(new UnitTestException());final CourseService service = new CourseServiceImpl(repository);service.createCourse("name");}@Testpublic void testUpdateCourse() {final Course expected = new Course();expected.setName("Alice");expected.setUuid("[uuid]");final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findCourseByUuid(any(String.class))).thenReturn(expected);when(repository.saveAndFlush(any(Course.class))).thenReturn(expected);final CourseService service = new CourseServiceImpl(repository);final Course actual = service.updateCourse(expected, "Bob");assertEquals("Bob", actual.getName());}@Test(expected = ObjectNotFoundException.class)public void testUpdateCourseMissing() {final Course expected = new Course();final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findCourseByUuid(any(String.class))).thenReturn(null);final CourseService service = new CourseServiceImpl(repository);service.updateCourse(expected, "Bob");}@Test(expected = PersistenceException.class)public void testUpdateCourseError() {final Course expected = new Course();expected.setUuid("[uuid]");final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findCourseByUuid(any(String.class))).thenReturn(expected);doThrow(new UnitTestException()).when(repository).saveAndFlush(any(Course.class));final CourseService service = new CourseServiceImpl(repository);service.updateCourse(expected, "Bob");}@Testpublic void testDeleteCourse() {final Course expected = new Course();expected.setUuid("[uuid]");final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findCourseByUuid(any(String.class))).thenReturn(expected);doNothing().when(repository).delete(any(Course.class));final CourseService service = new CourseServiceImpl(repository);service.deleteCourse(expected.getUuid());}@Test(expected = ObjectNotFoundException.class)public void testDeleteCourseMissing() {final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findCourseByUuid(any(String.class))).thenReturn(null);final CourseService service = new CourseServiceImpl(repository);service.deleteCourse("[uuid]");}@Test(expected = PersistenceException.class)public void testDeleteCourseError() {final Course expected = new Course();expected.setUuid("[uuid]");final CourseRepository repository = Mockito.mock(CourseRepository.class);when(repository.findCourseByUuid(any(String.class))).thenReturn(expected);doThrow(new UnitTestException()).when(repository).delete(any(Course.class));final CourseService service = new CourseServiceImpl(repository);service.deleteCourse(expected.getUuid());} }整合測試
集成測試已推遲到實現(xiàn)持久層。
源代碼
- 可從http://code.google.com/p/invariant-properties-blog/source/browse/student/student-business獲得源代碼。
翻譯自: https://www.javacodegeeks.com/2014/01/project-student-business-layer.html
編程填空:學生信息處理程序
總結(jié)
以上是生活随笔為你收集整理的编程填空:学生信息处理程序_项目学生:业务层的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么写微博 如何写微博
- 下一篇: 谁知道巨擎怎么读?什么意思 巨擎的意思