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

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

Unit tests - good practice when comparing object fields

问题

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

@Test
public void testCreateUserSnapshotWithInitializedUser() {
    //给定
    User user = aUser()
            .withUsername("Test")
            .withPassword("Pa$$word")
            .withEmail("example@example.com")
            .withRole(UserRole.COMMON)
            .buildInitialized();

    //当
    UserSnapshot snapshot = user.createSnapshot();

    //那么
    assertEquals("Test", snapshot.getUsername());
    assertEquals("Pa$$word", snapshot.getPassword());
    assertEquals("example@example.com", snapshot.getEmail());
    assertEquals(UserRole.COMMON, snapshot.getRole());
    assertEquals(true, snapshot.isEnabled());
}

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.

  @Test
    public void testCreateUserSnapshotWithInitializedUser() {
        //given
        User user = aUser()
                .withUsername("Test")
                .withPassword("Pa$$word")
                .withEmail("example@example.com")
                .withRole(UserRole.COMMON)
                .buildInitialized();

        //when
        UserSnapshot snapshot = user.createSnapshot();

        //then
        assertEquals("Test", snapshot.getUsername());
        assertEquals("Pa$$word", snapshot.getPassword());
        assertEquals("example@example.com", snapshot.getEmail());
        assertEquals(UserRole.COMMON, snapshot.getRole());
        assertEquals(true, snapshot.isEnabled());
    }

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

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

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

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestUtils {

    public static ObjectMapper mapper = new ObjectMapper();

    public static String mapToString(Object object) throws JsonProcessingException {
        return mapper.writeValueAsString(object);
    }
}

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

@Test
void testCreateUserSnapshotWithInitializedUser() {
    UserSnapshot mock = UserSnapshotMocks.createUserSnapshot();

    var result = testCreateUserSnapshotWithInitializedUser(user);
    assertEquals(TestUtils.mapToString(mock), TestUtils.mapToString(result));
}

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

英文:

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:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestUtils {

    public static ObjectMapper mapper = new ObjectMapper();

    public static String mapToString(Object object) throws JsonProcessingException {
        return mapper.writeValueAsString(object);
    }
}

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

@Test
void testCreateUserSnapshotWithInitializedUser() {
    UserSnapshot mock = UserSnapshotMocks.createUserSnapshot();

    var result = testCreateUserSnapshotWithInitializedUser(user);
    assertEquals(TestUtils.mapToString(mock), TestUtils.mapToString(result));
}

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:

确定