J'ai la fonction suivante, que je souhaite tester:
testM("get not existing People") { (for { peopleRef <- Ref.make(Vector(People())) failure = Swapi.>.people(2).provide(Test(peopleRef)) } yield assertM(failure, fail(Cause.die(ServiceException(s"No People with id 2"))) } )
Cette fonction renvoie People s'il y en a un pour cet id
, resp. échoue sinon, comme:
suite("Get a Person for an ID") ( testM("get Luke Skywalker") { for { peopleRef <- Ref.make(Vector(People())) luke <- Swapi.>.people(1).provide(Test(peopleRef)) } yield assert(luke, equalTo(People())) },
Le cas heureux fonctionne, comme:
IO.fail(ServiceException(s"No People with id $id"))
Mais comment puis-je tester le cas d'échec? J'ai essayé différentes choses, la plupart du temps les types ne correspondent pas. Voici une tentative:
def people(id: Int): RIO[R, People]
4 Réponses :
Avec l'aide de @adamfraser dans le ZIO-Chat :
Fondamentalement, appelez run sur votre effet d'échec, puis affirmez qu'il s'agit d'un échec avec Assertion.fails. Ou Assertion.dies s'il s'agit d'une exception non vérifiée.
Je pense que j'ai maintenant une bonne solution.
testM("get not existing People") { for { peopleRef <- Ref.make(Vector(People())) failure <- Swapi.>.people(2).provide(Test(peopleRef)).run } yield assert( failure, fails(equalTo(ServiceException("No People with id 2"))) ) }
D'autres solutions sont toujours les bienvenues.
Je pense que vous l'avez définitivement. La seule chose que j'ajouterais pour les autres avec des questions similaires est que votre exemple implique également un type d'environnement, qui est un excellent sujet de discussion mais quelque peu indépendant de la façon de tester qu'un effet échoue comme prévu en utilisant ZIO Test.
J'ai inclus ci-dessous un exemple minimal de la façon de tester qu'un effet échoue comme prévu. Comme mentionné ci-dessus, vous appelleriez run
sur l'effet pour obtenir une valeur de sortie, puis utilisez Assertion.fails
pour affirmer que l'effet échoue avec une exception vérifiée, Assertion.dies
pour affirmer que l'effet échoue avec une exception non vérifiée, ou Assertion.interrupted
pour tester qu'un effet a été interrompu.
Notez également que vous ne devez pas utiliser include equalTo("fail")
. Si tout ce qui vous importe, c'est que l'effet a échoué, vous pouvez simplement utiliser fails(anything)
. Si vous testez qu'un effet meurt avec une exception spécifiée, vous pouvez faire quelque chose comme dies(isSubtype[IllegalArgumentException])
.
J'espère que cela t'aides!
import zio.test._ import zio.test.Assertion._ import zio.ZIO object ExampleSpec extends DefaultRunnableSpec( suite("ExampleSpec")( testM("Example of testing for expected failure") { for { result <- ZIO.fail("fail") } yield assert(result, fails(equalTo("fail"))) } ) )
Pour mémoire, cet exemple ne fonctionne pas pour moi. J'essaie de trouver la façon la plus idiomatique de tester les échecs attendus et votre exemple semble que cela devrait fonctionner, mais il ne se compile pas pour moi. Erreur: incompatibilité de type (11, 37); trouvé: zio.test.Assertion [zio.Exit [Any, Any]] requis: zio.test.Assertion [String]} yield assert (result, failed (equalTo ("fail")))
Il semble que j'avais besoin d'ajouter .runs
à l'effet afin d'utiliser l'assertion d' fails
, c'est-à-dire ZIO.fail("fail").run
Vous pouvez également inverser les canaux d'erreur et de résultat:
import zio.test._ import zio.test.Assertion._ import zio.ZIO object ExampleSpec extends DefaultRunnableSpec( suite("ExampleSpec")( testM("Example of testing for expected failure") { for { result <- ZIO.fail("fail").flip } yield assert(result, equalTo("fail")) } ) )
gentil, merci - a peut-être besoin d'un commentaire pour être clair;)
Voici une autre variante compacte utilisant assertM
:
object ExampleSpec extends DefaultRunnableSpec { def spec = suite("ExampleSpec")( testM("Example of testing for expected failure") { assertM(ZIO.fail("fail").run)(fails(equalTo("fail"))) } ) }