【问题标题】:Java - Testing Simulation With MockitoJava - 使用 Mockito 测试模拟
【发布时间】:2018-11-20 21:22:37
【问题描述】:

我不太熟悉 Mockito,但我正在尝试使用 mock 来测试模拟的行为,这就是类:

package simulator;

import java.util.Map;

import org.apache.commons.lang3.Validate;
import simulator.enums.Team;
import simulator.fixtures.Fixture;

public class SimulateBasketballMatchResult implements Simulation<Team> {

    private final Fixture fixture;

    public SimulateBasketballMatchResult(Fixture fixture) {

        Validate.notNull(fixture, "fixture cannot be null");

        this.fixture = fixture;
    }

    @Override
    public Team simulate(Map<Team, Double> outcomeProbabilityMap) {

        Validate.notNull(outcomeProbabilityMap, "outcomeProbabilityMap cannot be null");

        final Team homeTeam = fixture.getHomeTeam();
        final Team awayTeam = fixture.getAwayTeam();

        double random = randomDoubleGenerator();

        double homeWinProbability = outcomeProbabilityMap.get(homeTeam);

        return random < homeWinProbability ? homeTeam : awayTeam;

    }

    public Double randomDoubleGenerator() {
        return Math.random();
    }

}

下面是测试类:

@RunWith(MockitoJUnitRunner.class)
public class SimulateBasketballMatchResultTest {

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    private static final Map<Team, Double> MATCH_RESULT_PROBABILITY_MAP = new HashMap<>();

    private static final Fixture FIXTURE = new Fixture(GOLDEN_STATE_WARRIORS, HOUSTON_ROCKETS, REGULAR_SEASON);

    static {
        MATCH_RESULT_PROBABILITY_MAP.put(FIXTURE.getHomeTeam(), 0.7d);
        MATCH_RESULT_PROBABILITY_MAP.put(FIXTURE.getAwayTeam(), 0.3d);
    }

    @Mock
    private SimulateBasketballMatchResult simulateBasketballMatchResult;

    @Test
    public void shouldReturnGoldenStateWarriorsAsWinner() {

        when(simulateBasketballMatchResult.randomDoubleGenerator()).thenReturn(0.5d);

        assertThat(simulateBasketballMatchResult.simulate(MATCH_RESULT_PROBABILITY_MAP), is(GOLDEN_STATE_WARRIORS));

    }

}

我想断言当概率范围在 0 到 0.7 之间时返回 GOLDEN_STATE_WARRIORS - 但是我的测试代码出现断言错误 null。

java.lang.AssertionError: 
Expected: is <GOLDEN_STATE_WARRIORS>
     but: was null
Expected :is <GOLDEN_STATE_WARRIORS>

【问题讨论】:

    标签: java unit-testing junit mocking mockito


    【解决方案1】:

    simulateBasketballMatchResult 是一个模拟对象,因此默认情况下,它将为其所有方法返回null(当然,它具有非原始返回值)。

    与其模拟该对象,不如窥探它:

    @Spy
    private SimulateBasketballMatchResult simulateBasketballMatchResult = 
        new SimulateBasketballMatchResult(Fixture);
    

    【讨论】:

      【解决方案2】:

      试试这个:

      @Mock
      private Fixture fixture;
      
      private SimulateBasketballMatchResult simulator;
      
      @Before
      public void setUp() {
          simulator = spy(new SimulateBasketballMatchResult(fixture));
          doCallRealMethod().when(simulator).simulate();
      }
      
      @Test
      public void shouldReturnGoldenStateWarriorsAsWinner() {
          doReturn(0.5).when(simulator).randomDoubleGenerator();
          when(fixture.getHomeTeam()).thenReturn(GOLDEN_STATE_WARRIORS);
          when(fixture.getAwayTeam()).thenReturn(HOUSTON_ROCKETS);
      
          assertThat(simulator.simulate(MATCH_RESULT_PROBABILITY_MAP), is(GOLDEN_STATE_WARRIORS));
      }
      

      Mockito.spy@Spy 允许您模拟 真实 对象的某些方法,但 Mockito.mock@Mock 模拟整个对象。

      mockito 中的 mock 是一个普通的 mock(允许您存根调用;也就是说,从方法调用中返回特定值)。

      mockito 中的 spy 是部分模拟(部分对象将被模拟,部分将使用真实的方法调用)。

      Read more

      【讨论】:

      • 这成功了!非常感谢。 spy 实际做了什么,它与模拟有何不同?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 2018-02-01
      • 1970-01-01
      • 2021-05-28
      • 1970-01-01
      相关资源
      最近更新 更多