英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论