Mockito验证构造函数调用方法

时间:2018-09-28 14:59:43

标签: java unit-testing mocking mockito

我试图测试何时实例化Game类,调用start方法。但是我收到以下错误:

Wanted but not invoked:
game.start();
Actually, there were zero interactions with this mock.

我有一个名为Game

的以下课程
public class Game {
    private Hand player_hand;
    private Hand dealer_hand;
    public static Boolean isInPlay;

    public Game() {
        player_hand = new Hand();
        dealer_hand = new Hand();
        start();
    }

    public void start() {
        isInPlay = true;
        player_hand.hit();
        player_hand.hit();
        System.out.println("Player hand: ");
        player_hand.printHands();
        instantWinLose();
        dealer_hand.hit();
        dealer_hand.hit();
    }
}

我有一个名为GameTest的测试班

@RunWith(MockitoJUnitRunner.StrictStubs.class)

public class GameTest {

@InjectMocks
Game game;

@Mock
Hand hand;

    @Test
    public void testGameConstruction() {
        Game mockedGame = mock(Game.class);
        verify(mockedGame, times(1)).start();
    }
}

我是Mockito的新手。我尝试过以下Difference between @Mock and @InjectMocks中的示例,但仍然遇到相同的错误

3 个答案:

答案 0 :(得分:2)

实际上,您需要调用start方法,然后只有时间才能验证您的模拟。

类似::   mockedGames.start()

然后只有它的呼叫会得到验证

答案 1 :(得分:1)

当您调用Mockito.mock(SomeType.class)时,Mockito将为该类型动态创建一个子类,但为了进行实例化,它使用某些技术来避免调用超级构造函数(read more)。

尝试一下:

public class Foobar {

    public Foobar () {
        throw new RuntimeException();
    }

}

// Somewhere else ...
Mockito.mock(Foobar.class); // No exception will be thrown because constructor is never called

当您考虑它时,这是有道理的:除非绝对需要,否则新的模拟对象不应执行任何操作(存根)。调用任何实际逻辑都可能会产生不良后果。

这就是为什么您永远不会嘲笑被测类!

当您自己模拟被测类时,您的测试完全没有意义!

仅模拟依赖项。

您的Game类没有依赖关系,因此您不需要任何模拟:

    @Test
    public void testGameConstruction() {
        Game game = new Game();
        assertTrue(game.isInGame());
    }

如果Game具有依赖性,例如Hand,则可以添加构造函数参数:

public Game (Hand hand1, Hand hand2) { .... }

然后:

    @Test
    public void testGameConstruction() {

        Hand handMock1 = Mockito.mock(Hand.class);
        Hand handMock2 = Mockito.mock(Hand.class);
        Game game = new Game(handMock1, handMock2);

        verify(handMock1, times(1)).hit();
        verify(handMock2, times(1)).hit();

    }

答案 2 :(得分:0)

我的理解是,通过模拟Game类,您还可以模拟构造函数。这意味着没有运行来自实际类构造器的代码。尝试创建Game类的实例而不进行模拟。