JPA实体必须经过单元测试,如何进行?

我有一个Spring MVC应用程序(Spring Boot 1.2.5版),该应用程序使用JPA与流行的Sql数据库进行交互。

因此,我有几个映射数据库中所有表的实体。显然,这些类仅具有用于实体之间关系的获取器/设置器和注释。

例如:

@Entity

@Table

public class Article {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

@JsonView(View.Private.class)

private Long id;

@Column(nullable = false)

@JsonView(View.Public.class)

private String name;

@ManyToOne(optional = false, fetch = FetchType.LAZY)

@JoinColumn(name = "categoryId", nullable = false, updatable = false)

@JsonIgnore

private Category category;

//Constructors Getters and Setters

...

}

我的问题是:我应该对这些课程进行单元测试吗?我应该测试什么?怎么样

回答:

我建议您测试所有编写的内容(或选择编写)…因此在这种情况下,我看到以下元素:

@GeneratedValue(strategy = GenerationType.IDENTITY)

@Column(nullable = false)

@ManyToOne(optional = false, fetch = FetchType.LAZY)

@JoinColumn(name = "categoryId", nullable = false, updatable = false)

您可以使用此批注定义一些行为(我仅从JPA中选择行为,而JSONView批注应完成相同的操作),并且如果一切正常,就想进行单元测试(如您所定义的)。

@Test(expect = SQLException.class)

public void should_not_allow_null_name() {

/* Given */ Article article = new Article(null, new Category());

/* When */ articleRepository.save(article);

}

通过这种(简单的)测试,您可以遵循行为是否符合您已实现的要求。如果有人(也许是您自己)删除了此注释,您将收到警报。

但是不要测试默认行为(例如,列名,您选择让JPA(和ORM)为您选择…)所以不要测试框架,这是极限。

关于如何进行测试,我喜欢使用(自Spring

Boot起)名为DBSetup的项目。它使我可以在测试中对数据集进行硬编码,而不是冗长的XML。这是忍者小队非常有趣的项目。

测试示例:

数据库测试配置:

@Configuration

@EnableJpaRepositories(basePackages = "lan.dk.podcastserver.repository")

@EntityScan(basePackages = "lan.dk.podcastserver.entity")

public class DatabaseConfiguraitonTest {

@Bean

public DataSource dataSource() {

return new EmbeddedDatabaseBuilder()

.setType(EmbeddedDatabaseType.H2)

.build();

}

@Bean

@Autowired

public FullTextEntityManager fullTextEntityManager(EntityManager entityManager) {

return getFullTextEntityManager(entityManager);

}

public static final DateTimeFormatter formatter = new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE).appendLiteral(" ").append(DateTimeFormatter.ISO_LOCAL_TIME).toFormatter();

public static final Operation DELETE_ALL_PODCASTS = deleteAllFrom("PODCAST");

public static final Operation DELETE_ALL_ITEMS = deleteAllFrom("ITEM");

public static final Operation DELETE_ALL_TAGS = sequenceOf(deleteAllFrom("PODCAST_TAG"), deleteAllFrom("TAG"));

public static final Operation DELETE_ALL = sequenceOf(DELETE_ALL_ITEMS, DELETE_ALL_TAGS, DELETE_ALL_PODCASTS, DELETE_ALL_TAGS);

}

==>

https://gist.github.com/davinkevin/bb4f62aaec031b68b8f3

并测试:

@Transactional

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(classes = {DatabaseConfiguraitonTest.class, HibernateJpaAutoConfiguration.class})

public class ItemRepositoryTest {

@Autowired DataSource dataSource;

@Autowired ItemRepository itemRepository;

private final static DbSetupTracker dbSetupTracker = new DbSetupTracker();

public static final Operation INSERT_REFERENCE_DATA = sequenceOf(

insertInto("PODCAST")

.columns("ID", "TITLE", "URL", "TYPE", "HAS_TO_BE_DELETED")

.values(1, "AppLoad", null, "RSS", false)

.values(2, "Geek Inc HD", "http://fake.url.com/rss", "YOUTUBE", true)

.build(),

insertInto("ITEM")

.columns("ID", "TITLE", "URL", "PODCAST_ID", "STATUS", "PUBDATE", "DOWNLOADDDATE")

.values(1L, "Appload 1", "http://fakeurl.com/appload.1.mp3", 1, Status.FINISH, now().minusDays(15).format(formatter), now().minusDays(15).format(formatter))

.values(2L, "Appload 2", "http://fakeurl.com/appload.2.mp3", 1, null, now().minusDays(30).format(formatter), null)

.values(3L, "Appload 3", "http://fakeurl.com/appload.3.mp3", 1, Status.NOT_DOWNLOADED, now().format(formatter), null)

.values(4L, "Geek INC 123", "http://fakeurl.com/geekinc.123.mp3", 2, Status.DELETED, now().minusYears(1).format(formatter), now().format(formatter))

.values(5L, "Geek INC 124", "http://fakeurl.com/geekinc.124.mp3", 2, Status.FINISH, now().minusDays(15).format(formatter), now().minusDays(15).format(formatter))

.build(),

insertInto("TAG")

.columns("ID", "NAME")

.values(1L, "French Spin")

.values(2L, "Studio Knowhere")

.build(),

insertInto("PODCAST_TAG")

.columns("PODCAST_ID", "TAG_ID")

.values(1, 1)

.values(2, 2)

.build()

);

@Before

public void prepare() throws Exception {

Operation operation = sequenceOf(DELETE_ALL, INSERT_REFERENCE_DATA);

DbSetup dbSetup = new DbSetup(new DataSourceDestination(dataSource), operation);

dbSetupTracker.launchIfNecessary(dbSetup);

}

@Test

public void should_find_by_podcast_and_page() {

/* Given */

dbSetupTracker.skipNextLaunch();

Integer podcastId = 1;

PageRequest pageRequest = new PageRequest(1, 1, Sort.Direction.ASC, "id");

/* When */

Page<Item> itemByPodcast = itemRepository.findByPodcast(podcastId, pageRequest);

/* Then */

PageAssert

.assertThat(itemByPodcast)

.hasSize(1)

.hasTotalElements(3)

.hasTotalPages(3)

.hasNumberOfElements(1);

ItemAssert

.assertThat(itemByPodcast.getContent().get(0))

.hasTitle("Appload 2");

}

==>

https://gist.github.com/davinkevin/df041729608dc21bf7f3

以上是 JPA实体必须经过单元测试,如何进行? 的全部内容, 来源链接: utcz.com/qa/416464.html

回到顶部