AssertNotNull AssertionFailedError: expected: not <null>

AssertNotNull AssertionFailedError: expected: not <null>

我正在测试一个应用程序,其中一个方法创建和对象,我正在尝试测试该对象实际上是这样创建的:

   @Test
public void testCreateWagerGetsCreated(){
    DefaultSportsBettingService service = mock(DefaultSportsBettingService.class);
    Player player = mock(Player.class);
    Outcome outcome = new Outcome(null,"description",BigDecimal.valueOf(2),false);
    BigDecimal bd = BigDecimal.valueOf(100);
    assertNotNull(service.createWager(player,outcome, bd));
}

但是测试失败并抛出此错误:

org.opentest4j.AssertionFailedError: expected: not <null>

    at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:39)
    at org.junit.jupiter.api.Assertions.fail(Assertions.java:134)
    at org.junit.jupiter.api.AssertNotNull.failNull(AssertNotNull.java:47)
    at org.junit.jupiter.api.AssertNotNull.assertNotNull(AssertNotNull.java:36)
    at org.junit.jupiter.api.AssertNotNull.assertNotNull(AssertNotNull.java:31)
    at org.junit.jupiter.api.Assertions.assertNotNull(Assertions.java:300)
    at com.epam.training.sportsbetting.Tester.testCreateWagerGetsCreated(Tester.java:64)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:306)
    at org.junit.runners.BlockJUnit4ClassRunner.evaluate(BlockJUnit4ClassRunner.java:100)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access0(ParentRunner.java:66)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:293)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

我尝试模拟域 classes 并实例化它们,两者都抛出相同的错误。 我做错了什么?

玩家class:

public class Player extends User{

private String name;

private BigDecimal balance;

private Currency currency;

public Player(){

}
public Player(String email, String password, String name, BigDecimal balance, Currency currency) {
    super(email, password);
    this.name = name;
    this.balance = balance;
    this.currency = currency;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public BigDecimal getBalance() {
    return balance;
}

public void setBalance(BigDecimal balance) {
    this.balance = balance;
}

public Currency getCurrency() {
    return currency;
}

public void setCurrency(Currency currency) {
    this.currency = currency;
}

@Override
public String toString() {
    return "Player{" +
            "name='" + name + '\'' +
            ", balance=" + balance +
            ", currency=" + currency +
            '}';
}

}

DefaultSportsBettingServiceclass:

    public class DefaultSportsBettingService implements SportsBettingService{

public DummyDataStore dds = new DummyDataStore();
public List <Player> initializedPlayers = dds.getPlayerDatastore();
public List<User> initializedUsers = dds.getUserDataStore();
public List<Outcome> outcomeDatastore = dds.getOutcomeDatastore();
public List<SportEvent> sportEventDataStore = dds.getSportEventDataStore();
public List<Wager> wagerDatastore = dds.getWagerDatastore();
public List<Bet> betsDataStore = dds.getBetDataStore();
Player loggedPlayer;

@Override
public Player authenticateUser(User login) throws AuthenticationException {
    Player find = new Player();

    for (Player player : initializedPlayers) {
            if (login.getEmail().equals(player.getEmail()) && login.getPassword().equals(player.getPassword())) {
                loggedPlayer = player;

            return loggedPlayer;
            }
    }
    throw new AuthenticationException("Incorrect email and/or password");
}

@Override
public List<Bet> findAllBets() {
    return dds.findAllBetVariations();
}

@Override
public Wager createWager(Player player, Outcome outcome, BigDecimal amount) throws LowBalanceException {

    Wager wager = new Wager();
    wager.setOutcome(outcome);
    wager.setPlayer(player);
    wager.setCurrency(player.getCurrency());
    wager.setTimeStampCreated(LocalDateTime.now());
    wager.setAmount(amount);
    if(getLoggedPlayer().getBalance().compareTo(amount) < 0){
        throw new LowBalanceException(loggedPlayer.getBalance().toString(), loggedPlayer.getCurrency());
    }
    getLoggedPlayer().setBalance(getLoggedPlayer().getBalance().subtract(amount));
    if(wager.getOutcome().isWin()){
        wager.setWin(true);
    }
    wagerDatastore.add(wager);
    return wager;
}

@Override
public List<Wager> findAllWagers() {
    return wagerDatastore;
}

@Override
public void calculateResults() {
    BigDecimal counter = BigDecimal.valueOf(0);
    for(int i = 0; i < wagerDatastore.size(); i++){

        if(wagerDatastore.get(i).isWin()){

            counter = counter.add(wagerDatastore.get(i).getOutcome().getOdd().multiply(wagerDatastore.get(i).getAmount()));
            wagerDatastore.get(i).getPlayer().setBalance(counter);
        }

    }
}

public Player getLoggedPlayer() {
    return loggedPlayer;
}

public void setLoggedPlayer(Player loggedPlayer) {
    this.loggedPlayer = loggedPlayer;
}

}

几个问题加在一起。

  1. DefaultSportsBettingService 是一个被测对象,所以你不想模拟它。

  2. 在你的例子中,NullPointerException 来自 getLoggedPlayer,因为 loggerPlayer 从未被初始化。

使测试变得糟糕的几个不太重要的事情:

  1. LocalDateTime.now() 是静态的,所以你无法测试它是否设置正确,所以最好将它作为外部参数传递(超出这些答案的范围)

近似解如下(无法在IDE中测试):

@ExtendWith(MockitoExtension.class)
class DefaultSportsBettingServiceTest {

    @Mock
    Player loggedPlayer

    @InjectMocks
    DefaultSportsBettingService service

    @Test
    public void testCreateWagerGetsCreated(){
        Mockito.when(loggedPlayer.getBalance()).thenReturn(BigDecimal.ZERO);
        Mockito.doNothing().when(loggedPlayer).setBalance(BigDecimal(15));
        Player player = Player(); // May require more params
        Outcome outcome = new Outcome(null,"description",BigDecimal.valueOf(2),false);
        BigDecimal bd = BigDecimal.valueOf(100);
        assertNotNull(service.createWager(player,outcome, bd));
    }

}

基本上,您模拟 loggedPlayer 并作为普通对象休息传递,并期望 service.createWager 正常工作。如果测试代码或测试值需要其他更正,Mockito 应该会从这里建议您。