2011-01-18 36 views
14

Lấy ví dụ rất cụ thể của lớp JpaDao quy định tại article này:Thử nghiệm đơn vị nào để viết cho một lớp bằng cách sử dụng Generics trong Java?

public abstract class JpaDao<K, E> implements Dao<K, E> { 
    protected Class<E> entityClass; 

    @PersistenceContext 
    protected EntityManager entityManager; 

    public JpaDao() { 
     ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass(); 
     this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1]; 
    } 

    public void persist(E entity) { entityManager.persist(entity); } 

    public void remove(E entity) { entityManager.remove(entity); } 

    public E findById(K id) { return entityManager.find(entityClass, id); } 
} 

nó sẽ là tốt nhất để viết các unit test cho tất cả các thực thể tồn tại trong ứng dụng (Order, Customer, Book, vv), hoặc nó sẽ được chấp nhận để viết các bài kiểm tra đơn vị cho chỉ một thực thể, như được gợi ý bởi điều này other question? Có bất kỳ thực hành tốt nhất liên quan đến đơn vị thử nghiệm các lớp học java sử dụng Generics?

Trả lời

6

Bạn có thể viết một lớp thử nghiệm trừu tượng cho các thực thể phân lớp này.

Ví dụ:

public abstract class JpaDaoTest<K,E> { 

    abstract protected E getEntity(); 
    abstract protected JpaDao getDAO(); 

    @Test 
    public void testPersistCreatesEntity() 
    { 
     JpaDao dao = getDAO(); 
     dao.persist(getEntity()); 
     // assert 
    } 
} 

Hợp đồng bạn lớp generic thực hiện sẽ có thể được kiểm tra cũng giống như genericlly, giả định rằng getEntity() bộ lên và phụ thuộc quan hệ một cách chính xác.

Vì vậy, bằng cách phân lớp lớp thử nghiệm này cho tất cả các trường hợp thử nghiệm cho các lớp con chung của bạn, bạn sẽ có được các bài kiểm tra miễn phí.

1

Nếu sử dụng loại thực thể khác sẽ khiến mã khác nhau thực thi, thì bạn cần một trường hợp thử nghiệm riêng biệt.

Tôi muốn kiểm tra nhiều nhất có thể trong một tập hợp thử nghiệm chung chỉ sử dụng một loại thực thể. Nếu hầu hết mã của bạn xử lý tất cả các thực thể giống nhau, thì không cần phải thử nghiệm nhiều hơn một lần. Tôi đã thiết lập các trường hợp thử nghiệm riêng biệt cho bất kỳ hành vi đặc biệt nào được yêu cầu khi DAO thực thể cụ thể có hành vi khác nhau.

1

Từ FAQ JUnit:

4) Trong những điều kiện tôi nên kiểm tra get() và thiết lập) phương pháp (?

Bài kiểm tra đơn vị nhằm mục đích giảm bớt nỗi sợ rằng có điều gì đó có thể xảy ra. Nếu bạn nghĩ rằng phương thức get() hoặc set() có thể bị phá vỡ một cách hợp lý, hoặc trên thực tế đã góp phần vào một lỗi, thì bằng mọi cách viết một bài kiểm tra.

Tóm lại, kiểm tra cho đến khi bạn tự tin. Những gì bạn chọn để kiểm tra là chủ quan, dựa trên kinh nghiệm và mức độ tin cậy của bạn. Hãy nhớ thực tế và tối đa hóa đầu tư thử nghiệm của bạn.

Nó cũng khẳng định:

"Thử nghiệm cho đến khi sợ hãi quay sang chán nản."

Tôi không nghĩ câu hỏi của bạn dành riêng cho generics vì câu hỏi sẽ vẫn như cũ ngay cả khi bạn không sử dụng Generics. Trong trường hợp này tôi sẽ chọn để kiểm tra một đối tượng (Hoặc là thực hoặc đóng hộp cho mục đích thử nghiệm). Khi bạn phát hiện ra các vấn đề sau đó viết các bài kiểm tra để giải quyết những thiếu sót cụ thể đó.

0

Nếu tôi cần kiểm tra hành vi của lớp liên quan đến ngữ nghĩa kiểu của nó, tôi sẽ đi kiểm tra các kiểu bất biến. Nói cách khác, cố gắng thiết lập một số xác nhận là đúng cho tất cả các loại kết hợp các loại, không chỉ những loại mà bạn mong muốn sử dụng mà là bất kỳ loại nào trong vũ trụ, kể cả những loại chưa được phát minh.Ví dụ:

private <K, E> void testTypes(K k, E e) { 
    JpaDao<K, E> dao = new JpaDaoImpl<K, E>(); 

    dao.persist(e); 

    assertEquals(dao.getById(e.getId()).getClass(), e.getClass()); 
} 

@Test 
public void testIntegerAndOrder() { 
    this.<Integer, Order>testTypes(10, new Order()); 
} 

Xem, không có vấn đề gì loại KE được, các khẳng định được kỳ vọng sẽ giữ (phương pháp testIntegerAndOrder() kiểm tra khẳng định này sử dụng một giá trị kiểu dữ liệu cụ).

Điều này, tất nhiên, nên được sử dụng kết hợp với các bài kiểm tra đơn vị, thực sự kiểm tra hành vi cho một số giá trị cụ thể của biến loại. Đây sẽ là rất nhiều bài kiểm tra đơn vị giống nhau mà bạn có thể tìm thấy trong bất kỳ hướng dẫn JUnit nào. Một cái gì đó trong tĩnh mạch của:

@Test 
public void testDao() throws Exception { 
    JpaDao<Integer, Order> dao = getDao(); 

    Order order = ...; 
    order.setId(10); 

    dao.persist(order); 

    assertEquals(order, dao.findById(10)); 
} 

Xem cách ngữ nghĩa của khẳng định sự khác biệt ở đây: kiểm tra thử nghiệm này một sự khẳng định rằng đối tượng được lưu trữ giữ ID của nó sử dụng một giá trị cụ thể của ID biến, không phải là loại biến như các thử nghiệm trước đó.

1

Giống như BalusC, tôi khuyên bạn nên thử nghiệm triển khai cụ thể. Lý do cho điều này là nó phù hợp với nguyên tắc "Bạn không phải là cần nó". Chỉ thêm các bài kiểm tra đủ để trường hợp sử dụng mà bạn đang cố triển khai. Sau đó, khi bạn thêm nhiều trường hợp sử dụng, hãy thêm các bài kiểm tra đơn vị khác.

0

Kiểm tra lớp bê tông tránh vấn đề ghi đè sau này.

Thật tuyệt vời khi thực hiện các thử nghiệm chung nhưng không an toàn.

Bạn có thể CopyPaste hầu hết các bài kiểm tra đơn vị trong quá trình phát triển và sau đó bạn có thể tùy chỉnh các bài kiểm tra.

Các vấn đề liên quan