单元测试 – 比较对象字段时的良好实践

huangapple go评论95阅读模式
英文:

Unit tests - good practice when comparing object fields

问题

我正在为我的Web应用程序编写单元测试。我开始想知道我所编写的是否是一种良好的实践。我的意思是,当一个对象创建其状态的快照,然后我比较新创建对象的字段值,以确定它们是否正确。

  1. @Test
  2. public void testCreateUserSnapshotWithInitializedUser() {
  3. //给定
  4. User user = aUser()
  5. .withUsername("Test")
  6. .withPassword("Pa$$word")
  7. .withEmail("example@example.com")
  8. .withRole(UserRole.COMMON)
  9. .buildInitialized();
  10. //当
  11. UserSnapshot snapshot = user.createSnapshot();
  12. //那么
  13. assertEquals("Test", snapshot.getUsername());
  14. assertEquals("Pa$$word", snapshot.getPassword());
  15. assertEquals("example@example.com", snapshot.getEmail());
  16. assertEquals(UserRole.COMMON, snapshot.getRole());
  17. assertEquals(true, snapshot.isEnabled());
  18. }

then 部分的断言数量是否太多了?或者我应该为每个断言分开创建适当的方法,例如:

assertUsernameIs("Test", snapshot);

或者创建一个方法,像这样:

assertSnapshotIsCorrect(snapshot);

英文:

I am writing unit tests for my web application. I started to wonder if what I am writing is a good practice. I mean when an object creates a snapshot of its state and I compare the field values of the newly created object to determine whether they are correct.

  1. @Test
  2. public void testCreateUserSnapshotWithInitializedUser() {
  3. //given
  4. User user = aUser()
  5. .withUsername("Test")
  6. .withPassword("Pa$$word")
  7. .withEmail("example@example.com")
  8. .withRole(UserRole.COMMON)
  9. .buildInitialized();
  10. //when
  11. UserSnapshot snapshot = user.createSnapshot();
  12. //then
  13. assertEquals("Test", snapshot.getUsername());
  14. assertEquals("Pa$$word", snapshot.getPassword());
  15. assertEquals("example@example.com", snapshot.getEmail());
  16. assertEquals(UserRole.COMMON, snapshot.getRole());
  17. assertEquals(true, snapshot.isEnabled());
  18. }

Is the amount of assertion in the then section is too overwhelming? Or should I separate appropriate methods for each asseration e.g.

assertUsernameIs("Test", snapshot);

Or create one method like:
assertSnapshotIsCorrect(snapshot);

答案1

得分: 0

如果你想要验证所有参数,以减少断言的数量,你可以在断言之前将对象映射为字符串。

通常,我会创建一个工具类来执行这种映射,就像这样:

  1. import com.fasterxml.jackson.core.JsonProcessingException;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. public class TestUtils {
  4. public static ObjectMapper mapper = new ObjectMapper();
  5. public static String mapToString(Object object) throws JsonProcessingException {
  6. return mapper.writeValueAsString(object);
  7. }
  8. }

然后,你可以只进行一次断言,比较结果和之前构建的模拟对象:

  1. @Test
  2. void testCreateUserSnapshotWithInitializedUser() {
  3. UserSnapshot mock = UserSnapshotMocks.createUserSnapshot();
  4. var result = testCreateUserSnapshotWithInitializedUser(user);
  5. assertEquals(TestUtils.mapToString(mock), TestUtils.mapToString(result));
  6. }

这样,你将会像比较一个字符串一样断言整个对象。

英文:

If you wanna validate all the parameters, to reduce the number of assertions, you can map the object to String before asserting.

I usually made a class utils to do this mapping, like that:

  1. import com.fasterxml.jackson.core.JsonProcessingException;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. public class TestUtils {
  4. public static ObjectMapper mapper = new ObjectMapper();
  5. public static String mapToString(Object object) throws JsonProcessingException {
  6. return mapper.writeValueAsString(object);
  7. }
  8. }

And then you can assert only once comparing the result and one previously build mock object:

  1. @Test
  2. void testCreateUserSnapshotWithInitializedUser() {
  3. UserSnapshot mock = UserSnapshotMocks.createUserSnapshot();
  4. var result = testCreateUserSnapshotWithInitializedUser(user);
  5. assertEquals(TestUtils.mapToString(mock), TestUtils.mapToString(result));
  6. }

This way you will assert the entire object like one and only String.

huangapple
  • 本文由 发表于 2023年7月18日 00:57:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76706624.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定