= Autre cas pratique

== @users

En décoration d'une méthode de test pour exécuter le test une fois par utilisateur.

IMPORTANT: Pas de rollback en fin de test pour l'utilisateur suivant !

[source,python]
----
from odoo.tests.common import users

@users("__system__", "user_sales_leads")
def test_for_user(self):
----

== with_user() et with_company()

Exécute la méthode avec l'utilisateur et/ou la compagnie choisie dans env

[source,python]
----
with self.with_user('user_sales_manager'):
    teams_data, members_data = self.sales_team_1._action_assign_leads(work_days=4)
----

== patch

Monkey patch l'attribut d'une instance ou d'une class par la nouvelle valeur

[source,python]
----
# self.patch(type ou instance, "attribut existant", nouvelle valeur)
from unittest.mock import patch
self.patch(self.env['res.users'], '_order', 'partner_id')
----

== Test bouchonné (MagicMock)

Méthode permettant différentes choses telles que patcher un attribut par une méthode ou toujours renvoyer le même résultat.

[source,python]
----
from unittest.mock import MagicMock

type(self.env["here.address.api"]).get_travel_matrix = MagicMock(
    return_value=[0, 2000, 8000, 2000, 0, 4000, 4000, 2000, 0]
)
----

IMPORTANT: S'applique à l'échelle de la class !

Plus d'information sur https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock

== Tests avec _queue jobs_

[IMPORTANT]
--
Les jobs ne sont pas exécutés automatiquement pendant les tests. Il faut donc exécuter la méthode voulue manuellement.

Il existe bien la variable d'environnement `TEST_QUEUE_JOB_NO_DELAY` et le context `test_queue_job_no_delay` qui exécute directement la méthode plutôt que de la mettre dans un job, mais leur utilisation est déconseillée car sans délai, cela ne représente pas le comportement réel des jobs, et le context reste ensuite sur l'objet, risquant d'affecter la mise en job d'une autre méthode s'il n'est pas retirer manuellement.
--

Pour tester des _queue jobs_, il faut au minimum deux méthodes de test :

* une qui s'assure que le job est bien dans la file avec les bons paramètres
* une qui test directement la méthode appelée par le job

Pour capturer le job, il faut utiliser `trap_jobs()` en gestionnaire de contexte.

.Exemple de test pour un _queue job_
[source,python]
----
from odoo.addons.queue_job.tests.common import trap_jobs

def my_job_method(self, name):
    rec = self.create([{"name": name}])
    return rec

def cron_method(self):
    self.with_delay(priority=15).my_job_method(name="Hello world")

# Premier test qui vérifie qu'un job est bien dans la file et que les
# paramètres sont ceux attendus
def test_enqueued_job(self):
    with trap_jobs() as trap:
        self.env["model"].cron_method()

        trap.assert_jobs_count(1, only=self.env["model"].my_job_method)
        trap.assert_enqueued_job(
            self.env["model"].my_job_method,
            kwargs=dict(name=expected_count),
            properties=dict(priority=15)
        )

 # Second test qui vérifie le fonctionnement de la méthode du job
 def test_my_job_method(self):
     record = self.env["model"].my_job_method(name="Hello world")
     self.assertEqual(record.name, "Hello world")
----
