Diferencia entre @Mock y @InjectMocks

Resuelto user2249972 asked hace 11 años • 0 respuestas

¿ Cuál es la diferencia entre @Mocky @InjectMocksen el marco Mockito?

user2249972 avatar May 10 '13 00:05 user2249972
Aceptado

@Mockcrea una burla. @InjectMockscrea una instancia de la clase e inyecta los simulacros que se crean con las anotaciones @Mock(o @Spy) en esta instancia.

Tenga en cuenta que debe utilizar @RunWith(MockitoJUnitRunner.class)o Mockito.initMocks(this)para inicializar estos simulacros e inyectarlos (JUnit 4).

Con JUnit 5, debes usar @ExtendWith(MockitoExtension.class).

@RunWith(MockitoJUnitRunner.class) // JUnit 4
// @ExtendWith(MockitoExtension.class) for JUnit 5
public class SomeManagerTest {

    @InjectMocks
    private SomeManager someManager;

    @Mock
    private SomeDependency someDependency; // this will be injected into someManager
 
     // tests...

}
Tom Verelst avatar May 09 '2013 17:05 Tom Verelst

Este es un código de muestra sobre cómo @Mocky @InjectMocksfunciona.

Digamos que tenemos Gamey Playerclase.

class Game {

    private Player player;

    public Game(Player player) {
        this.player = player;
    }

    public String attack() {
        return "Player attack with: " + player.getWeapon();
    }

}

class Player {

    private String weapon;

    public Player(String weapon) {
        this.weapon = weapon;
    }

    String getWeapon() {
        return weapon;
    }
}

Como puede ver, Gamela clase necesita Playerrealizar un attack.

@RunWith(MockitoJUnitRunner.class)
class GameTest {

    @Mock
    Player player;

    @InjectMocks
    Game game;

    @Test
    public void attackWithSwordTest() throws Exception {
        Mockito.when(player.getWeapon()).thenReturn("Sword");

        assertEquals("Player attack with: Sword", game.attack());
    }

}

Mockito se burlará de una clase Player y su comportamiento usando whenun thenReturnmétodo. Por último, usar @InjectMocksMockito lo colocará Playeren Game.

Tenga en cuenta que ni siquiera tiene que crear un new Gameobjeto. Mockito lo inyectará por ti.

// you don't have to do this
Game game = new Game(player);

También obtendremos el mismo comportamiento usando @Spyla anotación. Incluso si el nombre del atributo es diferente.

@RunWith(MockitoJUnitRunner.class)
public class GameTest {

  @Mock Player player;

  @Spy List<String> enemies = new ArrayList<>();

  @InjectMocks Game game;

  @Test public void attackWithSwordTest() throws Exception {
    Mockito.when(player.getWeapon()).thenReturn("Sword");

    enemies.add("Dragon");
    enemies.add("Orc");

    assertEquals(2, game.numberOfEnemies());

    assertEquals("Player attack with: Sword", game.attack());
  }
}

class Game {

  private Player player;

  private List<String> opponents;

  public Game(Player player, List<String> opponents) {
    this.player = player;
    this.opponents = opponents;
  }

  public int numberOfEnemies() {
    return opponents.size();
  }

  // ...

Esto se debe a que Mockito verificará la Type Signatureclase Game, que es Playery List<String>.

aldok avatar Oct 13 '2017 10:10 aldok