Are there any ways to simplify those codes?

I’m using Kotlin and SpringBoot to write a website. I wrote these codes for my DAOs testing.

       //Change Password
        userDao.createUser("test5", "Test 5", "123456".toByteArray())
        val changePasswordSalt = userDao.getLoginSalt("test5")
        Assertions.assertEquals(userDao.changePassword("test5", genHashedPassword("111111".toByteArray(), changePasswordSalt), "222222".toByteArray()), false)
        Assertions.assertEquals(userDao.changePassword("test5", genHashedPassword("123456".toByteArray(), changePasswordSalt), "654321".toByteArray()), true)

        //Change Nick Name
        userDao.createUser("test6", "Test 6", "123456".toByteArray())
        val changeNickNameSalt = userDao.getLoginSalt("test6")
        Assertions.assertEquals(userDao.changeNickName("test6", genHashedPassword("111111".toByteArray(), changeNickNameSalt), "6 Test"), false)
        Assertions.assertEquals(userDao.changeNickName("test6", genHashedPassword("123456".toByteArray(), changeNickNameSalt), "6 Test"), true)

        //Change Permission
        userDao.createUser("test7", "Test 7", "123456".toByteArray())
        val changePermissionSalt = userDao.getLoginSalt("test7")
        Assertions.assertEquals(userDao.changePermission("test7", genHashedPassword("111111".toByteArray(), changePermissionSalt), true), false)
        Assertions.assertEquals(userDao.changePermission("test7", genHashedPassword("123456".toByteArray(), changePermissionSalt), true), true)

Could I simplify these codes? If I can, What should I do?

I think your code would be more readable if you would put more logic into your User object. The responsibility of a “DAO” is typically persistence and not mutating the object to be persisted or read.

It is unclear to me, why the hashed password should be passed to a DAO to change a nickname. The DAO is then not only responsible for changing the domain object User, but also for authentication! I’d suggest the following:

  • User: (in context of security): hold and mutate nickname and password, check password
  • DAO: Save and find Users
  • UserService: perform authorization (maybe through a Spring Security annotation)

But apart from that, you could use more lightweight assertions like AssertJ (medium weight :wink:) or some Kotlin assertion library like the one from Kotest.

I hope that the code above is from three different test functions. If that is the case, you can remove the deleteAll call, since a @SpringBootTest runs in a transaction that is rolled back after the test.

However, I suggest to take a step back and think about what you really want to test. Let’s say you want to change the password, then you could

  • create a user and set a password
  • change the password
  • check, if the user can be authenticated with this password (no need to compare the password itself)

My fictional test case would look like this:

fun `should change password`() { 
    val user = User("Harry", "secret")
    user.changePassword("secret", "new secret")

    user.authenticate("new secret") shouldBe true

In this case you wouldn’t need persistence (and hence no Spring integration test - a usual unit test would be enough). The salt is an implementation detail and must not be provided from the outside (it is enough if the user object knows the salt).


Thanks, medium.
I’m new to SpringBoot and Kotlin, I will check out Kotest and rethink my code.