[Java] @Mock과 @InjectMocks의 차이점


Answers

테스트 클래스에서 테스트 된 클래스에는 @InjectMocks가 주석으로 표시되어야합니다. 이것은 Mockito에게 mock을 주입 할 클래스를 알려줍니다.

@InjectMocks
private SomeManager someManager;

그 다음부터는 클래스 내부의 특정 메소드 나 오브젝트 (이 경우 SomeManager )를 mock 으로 대체 할 수 있습니다.

@Mock
private SomeDependency someDependency;

이 예제에서는 SomeManager 클래스의 SomeDependency가 조롱을받습니다.

Question

Mockito 프레임 워크에서 @Mock@InjectMocks 의 차이점은 무엇입니까?




@Mock@InjectMocks 작동하는 방법에 대한 샘플 코드입니다.

Game and Player 클래스가 있다고 가정 해보십시오.

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;
    }
}

아시다시피, Game 클래스는 attack 을 수행하기 위해 Player 가 필요 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는 Player 클래스를 모의합니다. whenthenReturn 메소드를 사용하는 동작입니다. 마지막으로 @InjectMocks Mockito를 사용하면 해당 PlayerGame 넣을 수 있습니다.

new Game 객체를 만들지 않아도된다는 점에 유의하십시오. 모키 토가 당신을 위해 주사합니다.

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

@Spy 주석을 사용하여 동일한 동작을 @Spy . 속성 이름이 다른 경우에도 마찬가지입니다.

@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();
  }

  // ...

이는 Mockito가 Player 클래스 및 List<String> 인 Game 클래스의 Type Signature 를 검사하기 때문입니다.




  • @Mock 은 필요한 클래스에 대한 모의 구현을 만듭니다.
  • @InjectMock 은 클래스의 인스턴스를 생성하고 @Mock 어노테이션으로 표시된 모의 객체를 주입합니다.

예를 들어

@Mock
StudentDao studentDao;

@InjectMocks
StudentService service;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
}

여기서 우리는 서비스 클래스를위한 dao 클래스가 필요하다. 그래서 우리는 그것을 조롱하고 서비스 클래스 인스턴스에 삽입합니다. 비슷하게, Spring 프레임 워크에서 모든 @Autowired bean은 jUnits에서 @Mock으로 조롱되고 @InjectMocks를 통해 bean으로 주입 될 수 있습니다.

MockitoAnnotations.initMocks (this) 메소드는 이러한 mock을 초기화하고 모든 테스트 메소드에 대해이를 주입하여 setUp 메소드에서 호출해야합니다.

이 링크에는 Mockito 프레임 워크에 대한 좋은 자습서가 있습니다.