Cuối cùng tôi sử dụng giải pháp này.
Đối với Domain Model của tôi, tôi sử dụng liên kết này http://www.javacodegeeks.com/2014/09/tips-for-unit-testing-javabeans.html
/**
* @param <T>
*/
public abstract class AbstractJavaBeanTest<T> {
protected String[] propertiesToBeIgnored;
protected abstract T getBeanInstance();
@Test
public void beanIsSerializable() throws Exception {
final T myBean = getBeanInstance();
final byte[] serializedMyBean = SerializationUtils.serialize((Serializable) myBean);
@SuppressWarnings("unchecked")
final T deserializedMyBean = (T) SerializationUtils.deserialize(serializedMyBean);
assertEquals(myBean, deserializedMyBean);
}
@Test
public void equalsAndHashCodeContract() {
EqualsVerifier.forClass(getBeanInstance().getClass()).suppress(Warning.STRICT_INHERITANCE, Warning.NONFINAL_FIELDS).verify();
}
@Test
public void getterAndSetterCorrectness() throws Exception {
final BeanTester beanTester = new BeanTester();
beanTester.getFactoryCollection().addFactory(LocalDateTime.class, new LocalDateTimeFactory());
beanTester.testBean(getBeanInstance().getClass());
}
class LocalDateTimeFactory implements Factory {
@Override
public LocalDateTime create() {
return LocalDateTime.now();
}
}
}
/**
* Test Foo
*/
public class FooTest extends AbstractJavaBeanTest<Foo> {
@Override
protected Foo getBeanInstance() {
return new Foo();
}
}
tôi thêm này DEPENDENCIES để pom.xml:
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>1.7.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.meanbean</groupId>
<artifactId>meanbean</artifactId>
<version>2.0.3</version>
</dependency>
Đối với bộ điều khiển MVC của tôi, tôi sử dụng liên kết này http://www.luckyryan.com/2013/08/24/unit-test-controllers-spring-mvc-test/
/**
* Test FooController
*/
public class FooControllerTest {
@Mock
private FooService fooService;
@InjectMocks
private FooController fooController;
private MockMvc mockMvc;
@Before
public void setup() {
// Process mock annotations
MockitoAnnotations.initMocks(this);
// Setup Spring test in standalone mode
this.mockMvc = MockMvcBuilders.standaloneSetup(fooController).build();
}
@Test
public void testAdd() throws Exception {
Foo foo = new Foo();
// given
given(FooService.createFoo()).willReturn(foo);
// when
// then
this.mockMvc.perform(get("/foo/new"))
.andExpect(forwardedUrl("foo/detail"))
.andExpect(model().attributeExists("foo"))
.andExpect(model().attribute("foo", is(foo)));
}
@Test
public void testDetail() throws Exception {
Foo foo = new Foo();
Long fooId = 1L;
// given
given(fooService.findById(fooId)).willReturn(foo);
// when
// then
this.mockMvc.perform(get("/foo/" + fooId))
.andExpect(forwardedUrl("foo/detail"))
.andExpect(view().name("foo/detail"))
.andExpect(model().attributeExists("foo"))
.andExpect(model().attribute("foo", is(foo)));
}
@Test
public void testSave() throws Exception {
Foo foo = new Foo();
// given
// when
// then
//With form errors
this.mockMvc.perform(post("/foo/update")
.param("name", "")
.sessionAttr("foo", foo))
.andExpect(forwardedUrl("foo/detail"))
.andExpect(model().hasErrors())
.andExpect(model().attributeHasFieldErrors("foo", "name"));
//Without form errores
this.mockMvc.perform(post("/foo/update")
.param("name", "nameValue")
.param("code", "codeValue")
.param("date", "20/10/2015")
.requestAttr("referer", "/foo/list")
.sessionAttr("foo", foo))
.andExpect(view().name("redirect:" + "/foo/list"))
.andExpect(model().hasNoErrors())
.andExpect(flash().attributeExists("message"))
.andExpect(flash().attribute("message", hasProperty("message", is("message.ok"))))
.andExpect(flash().attribute("message", hasProperty("type", is(Message.Type.SUCCESS))))
.andExpect(status().isFound());
}
@Test
public void testDelete() throws Exception {
Foo foo = new Foo();
foo.setOtherFoos(new ArrayList<OtherFoo>());
Long fooId = 1L;
// given
given(fooService.findByIdWithOtherFoos(fooId)).willReturn(foo);
// when
// then
//Without errors: without other foos
this.mockMvc.perform(post("/foo/delete/" + fooId)
.sessionAttr("foo", foo)
.requestAttr("referer", "/foo/list"))
.andExpect(view().name("redirect:" + "/foo/list"))
.andExpect(flash().attributeExists("message"))
.andExpect(flash().attribute("message", hasProperty("message", is("message.ok"))))
.andExpect(flash().attribute("message", hasProperty("type", is(Message.Type.SUCCESS))));
// given
foo.getOtherFoos().add(new OtherFoo());
given(fooService.findByIdWithOtherFoos(fooId)).willReturn(foo);
// when
// then
//With errors: with other foos
this.mockMvc.perform(post("/foo/delete/" + fooId)
.sessionAttr("foo", foo)
.requestAttr("referer", "/foo/list"))
.andExpect(view().name("redirect:" + "/foo/list"))
.andExpect(flash().attributeExists("message"))
.andExpect(flash().attribute("message", hasProperty("message", is("message.error"))))
.andExpect(flash().attribute("message", hasProperty("type", is(Message.Type.DANGER))));
}
}
Để kiểm tra dịch vụ JUnit của tôi, tôi đã triển khai lớp cho cấu hình và tôi tải nó trong các thử nghiệm dịch vụ
@Configuration
public class FooServiceImplTestConfiguration {
@Bean
public FooService fooService() {
return new FooServiceImpl();
}
@Bean
public FooRepository fooRepository() {
return Mockito.mock(FooRepository.class);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {FooServiceImplTestConfiguration.class})
public class FooServiceImplTest {
@Inject
private FooRepository fooRepository;;
@Inject
private FooService fooService;
@BeforeClass
public static void oneTimeSetUp() {
// one-time initialization code
System.out.println("@BeforeClass - oneTimeSetUp");
}
@AfterClass
public static void oneTimeTearDown() {
// one-time cleanup code
System.out.println("@AfterClass - oneTimeTearDown");
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void createFoo() {
assertNotNull(fooService.createFoo());
}
@Test
public void save() {
//New foo
Foo saveFoo = new Foo();
// given
// when
fooService.save(saveFoo);
// then
assertNotNull(saveFoo.getDate());
saveFoo.setId(1L);
Date date = new Date();
saveFoo.setDate(date);
// given
//when
fooService.save(saveFoo);
//then
assertThat(date, is(saveFoo.getDate()));
}
@Test
public void delete() {
//given
//when
fooService.deleteFoo(Matchers.anyLong());
//then
}
@Test
public void findById() {
Long id = 1L;
Foo fooResult = new Foo();
//given
given(fooRepository.findOne(id)).willReturn(fooResult);
//when
Foo foo = fooService.findById(id);
//then
assertThat(foo, is(fooResult));
}
@Test
public void findByIdWithOtherFoos() {
Long id = 1L;
Foo fooResult = new Foo();
//given
given(fooRepository.findOne(id)).willReturn(fooResult);
//when
Foo foo = fooService.findByIdWithOtherFoos(id);
//then
assertThat(foo, is(fooResult));
}
@Test
public void findAll() {
Page<Foo> fooResult = new PageImpl<>(new ArrayList<Foo>());
given(fooRepository.findAll(Matchers.<Pageable>anyObject())).willReturn(fooResult);
//when
Page<Foo> foos = fooService.findAll(Matchers.<Pageable>anyObject());
//then
assertThat(foos, is(fooResult));
}
@Test
public void findAllList() {
List<Foo> fooResult = new ArrayList<Foo>();
given(fooRepository.findAll(Matchers.<Sort>anyObject())).willReturn(fooResult);
//when
List<Foo> foos = fooService.findAll(Matchers.<Sort>anyObject());
//then
assertThat(foos, is(fooResult));
}
}
Trong pom của tôi, tôi cần thêm sự phụ thuộc này:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
<!-- This is for mocking the service -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<!-- Optional -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
tôi cần thay đổi phiên bản Hibernate validator của tôi cho điều này:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.3.Final</version>
</dependency>
Tôi cũng cần thêm phụ thuộc này nữa vì tôi đã nhận được phép này:
Nguyên nhân: ja va.lang.AbstractMethodError: org.hibernate.validator.internal.engine.ConfigurationImpl.getDefaultParameterNameProvider() Ljavax/validation/ParameterNameProvider;
Thông báo chi tiết: org.hibernate.validator.internal.engine.ConfigurationImpl.getDefaultParameterNameProvider() Ljavax/validation/ParameterNameProvider;
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>el-impl</artifactId>
<version>2.2</version>
</dependency>
Tôi đang sử dụng dữ liệu mùa xuân, tôi cũng cần thực hiện kiểm tra cho CrudRepositories tùy chỉnh của mình.
Cách "tốt nhất" khá rộng. Có rất nhiều thứ mà bạn có thể thử nghiệm với tài nguyên này theo nhiều cách khác nhau, và không có cách nào là tổng thể * tốt nhất * cách. – Makoto
"để bao gồm tất cả các điều kiện hợp lý" là yêu cầu kiểm tra toàn diện, điều này không thực tế đối với mã thực tế. – Raedwald
Bạn muốn kiểm tra những gì? Mã Java trong bộ điều khiển của bạn? Mã Java trong lớp dịch vụ của bạn? @RequestMapping? Bộ chuyển đổi tin nhắn được sử dụng? Nếu bạn muốn kiểm tra tất cả chúng, câu hỏi này quá rộng. Nếu bạn muốn kiểm tra chỉ một câu hỏi này là không rõ ràng. – Raedwald