code: def test_async_evaluator_evaluate_if_necessary(
      save_best_so_far_agent, n_episodes
  ):
      outdir = tempfile.mkdtemp()
  
      # MagicMock can mock eval_mode while Mock cannot
      agent = mock.MagicMock()
      agent.act.return_value = "action"
      agent.get_statistics.return_value = []
  
      env = mock.Mock()
      env.reset.return_value = "obs"
      env.step.return_value = ("obs", 0, True, {})
      env.get_statistics.return_value = []
  
      evaluation_hook = mock.create_autospec(
          spec=pfrl.experiments.evaluation_hooks.EvaluationHook
      )
  
      agent_evaluator = evaluator.AsyncEvaluator(
          n_steps=None,
          n_episodes=n_episodes,
          eval_interval=3,
          outdir=outdir,
          max_episode_len=None,
          step_offset=0,
          evaluation_hooks=[evaluation_hook],
          save_best_so_far_agent=save_best_so_far_agent,
      )
  
      agent_evaluator.evaluate_if_necessary(
          t=1, episodes=1, env=env, agent=agent
      )
      assert agent.act.call_count == 0
      assert evaluation_hook.call_count == 0
  
      agent_evaluator.evaluate_if_necessary(
          t=2, episodes=2, env=env, agent=agent
      )
      assert agent.act.call_count == 0
      assert evaluation_hook.call_count == 0
  
      # First evaluation
      agent_evaluator.evaluate_if_necessary(
          t=3, episodes=3, env=env, agent=agent
      )
      assert agent.act.call_count == n_episodes
      assert agent.observe.call_count == n_episodes
      assert evaluation_hook.call_count == 1
      if save_best_so_far_agent:
          assert agent.save.call_count == 1
      else:
          assert agent.save.call_count == 0
  
      # Second evaluation with the same score
      agent_evaluator.evaluate_if_necessary(
          t=6, episodes=6, env=env, agent=agent
      )
      assert agent.act.call_count == 2 * n_episodes
      assert agent.observe.call_count == 2 * n_episodes
      assert evaluation_hook.call_count == 2
      if save_best_so_far_agent:
          assert agent.save.call_count == 1
      else:
          assert agent.save.call_count == 0
  
      # Third evaluation with a better score
      env.step.return_value = ("obs", 1, True, {})
      agent_evaluator.evaluate_if_necessary(
          t=9, episodes=9, env=env, agent=agent
      )
      assert agent.act.call_count == 3 * n_episodes
      assert agent.observe.call_count == 3 * n_episodes
      assert evaluation_hook.call_count == 3
      if save_best_so_far_agent:
          assert agent.save.call_count == 2
      else:
          assert agent.save.call_count == 0
  
file_path: pfrl/tests/experiments_tests/test_evaluator.py
imports: import tempfile
  import unittest
  from unittest import mock
  import numpy
  import pytest
  import pfrl
  from pfrl.experiments import evaluator
label_desc: Use image node_id 2 for calling a global function with example usage: test_async_evaluator_evaluate_if_necessary(save_best_so_far_agent, n_episodes) without return types