code: def test_mmf_loss(self):
      get_loss_class_mock = MagicMock(
          side_effect=build_loss_side_effect()
      )
      registry.get_loss_class = get_loss_class_mock
      # Test if MMFLoss accepts empty parameters
      self.assertRaises(ValueError, losses.MMFLoss)
      self.assertTrue(
          losses.MMFLoss({"type": "cross_entropy"}).name,
          "cross_entropy",
      )
      self.assertTrue(
          losses.MMFLoss("cross_entropy").name, "cross_entropy"
      )
      self.assertRaises(AssertionError, losses.MMFLoss, [])
      # Multi requires dict
      self.assertRaises(AssertionError, losses.MMFLoss, "multi")
  
      cross_entropy = losses.MMFLoss("cross_entropy")
      cross_entropy_from_dict = losses.MMFLoss(
          {"type": "cross_entropy"}
      )
      sample_list = SampleList()
      sample_list.dataset_type = "val"
      sample_list.dataset_name = "vqa2"
  
      output = cross_entropy(sample_list, {})
      output_from_dict = cross_entropy_from_dict(sample_list, {})
  
      self.assertEqual(
          output, {"val/vqa2/cross_entropy": torch.tensor(1.0)}
      )
      self.assertEqual(output_from_dict, output)
  
      get_loss_class_mock.side_effect = build_loss_side_effect(1.0)
      output = cross_entropy(sample_list, {})
  
      self.assertEqual(
          output, {"val/vqa2/cross_entropy": torch.tensor(1.0)}
      )
      self.assertEqual(output_from_dict, output)
  
      self.assertTrue(get_loss_class_mock.called)
      self.assertEqual(get_loss_class_mock.call_count, 5)
  
imports: import collections
  import unittest
  from unittest.mock import MagicMock
  import mmf.modules.losses
  import torch
  import torch.nn
  import torch.nn.functional
  from mmf.common.registry import registry
  from mmf.common.sample import SampleList
label_desc: Use image node_id 3 for calling the TestModuleLosses obj's underlying member method code with example usage: obj.test_mmf_loss() without return types