import zio.UIO
import zio.test.mock.Expectation._
import zio.test.mock.MockEnvironment
import zio.test.mock.MockSupport
import zio.test.mock.fake._
object UserServiceSpec extends DefaultRunnableSpec {
val mockUserRepo: MockUserRepository.Service[Any, Nothing] = new MockUserRepository.Service[Any, Nothing] {
def createUser(username: String): UIO[Unit] = unit
def getUser(username: String): UIO[Option[User]] = UIO(Some(User(username)))
}
val mockEnv: MockEnvironment = MockSupport.mockEnvironment[MockUserRepository](mockUserRepo)
def spec = suite("UserServiceSpec")(
testM("createUser should create a user") {
val result = UserService.createUser("John").provide(mockEnv)
assertM(result, equalTo(Unit))
},
testM("getUser should return the user") {
val result = UserService.getUser("John").provide(mockEnv)
assertM(result, equalTo(Some(User("John"))))
}
).provideCustomLayer(mockUserRepo)
case class User(username: String)
trait UserRepository {
def createUser(username: String): UIO[Unit]
def getUser(username: String): UIO[Option[User]]
}
object MockUserRepository extends UserRepository with Mock[UserRepository] {
object Service extends Service
trait Service extends UserRepository.Service[Any] {
def createUser(username: String): UIO[Unit] = mockEffect(Service.createUser, username)
def getUser(username: String): UIO[Option[User]] = mockEffect(Service.getUser, username)
}
}
object UserService {
def createUser(username: String): UIO[Unit] = UserRepo.createUser(username)
def getUser(username: String): UIO[Option[User]] = UserRepo.getUser(username)
object UserRepo extends UserRepository.Service[Any]
}
}