Spring MongoDB的单元测试返回空

f0brbegy  于 2022-09-18  发布在  Spring
关注(0)|答案(1)|浏览(172)

我正在尝试对我的基于MongoDB的Spring Boot应用程序进行单元测试,但我收到了一个java.lang.NullPointerException: Cannot invoke "blueprint.model.Garage.getCarModel()" because "savedGarage" is null错误。代码如下:

我的服务:

@Service
public class GarageService {

private final GarageRepository garageRepository;

@Autowired
public GarageService(GarageRepository garageRepository) {
    this.garageRepository = garageRepository;
}

public void addToGarage(Garage garage) {
    Optional<Garage> garageOptional = garageRepository.findByCarModel(garage.getCarModel());
    if(garageOptional.isPresent()) {
        throw new IllegalStateException("This Car model is already in our garage!");
    }
    garageRepository.save(garage);
}

public List<Garage> showOurGarage() {
    return garageRepository.findAll();
}

public void deleteFromGarage(String id) {
    boolean exists = garageRepository.existsById(id);
    if(!exists) {
        throw new IllegalStateException("A car with id " + id + " is not in our Garage.");
    }
    garageRepository.deleteById(id);
}

public void updateCar(String id, String carModel, Integer HP, Integer year, String designer) {
    Garage garage = garageRepository.findById(id)
            .orElseThrow(() -> new IllegalStateException(
                    "A car with the id " + id + " is not in our Garage."));
    if(carModel != null && carModel.length() > 0 && !Objects.equals(garage.getCarModel(), carModel)) {
        garage.setCarModel(carModel);
    }
    if(HP != null && !Objects.equals(garage.getHP(), HP)) {
        garage.setHP(HP);
    }
    if(year != null && !Objects.equals(garage.getYear(), year)) {
        garage.setYear(year);
    }
    if(designer != null && designer.length() > 0 && !Objects.equals(garage.getDesigner(), designer)) {
        garage.setDesigner(designer);
    }
    garageRepository.save(garage);
}
}

我的存储库:

@org.springframework.stereotype.Repository
public interface GarageRepository extends MongoRepository<Garage, String> {

Optional<Garage> findByCarModel(String carModel);

这是一个测试:

@DisplayName("Garage Service Test")
@DataMongoTest
class GarageServiceTest {

@Mock
private GarageRepository garageRepository;
private GarageService garageService;

@BeforeEach
void setUp() {
    MockitoAnnotations.openMocks(this);
    garageService = new GarageService(garageRepository);
}

@Test
@DisplayName("Add Car To Garage Test")
void testAddToGarage() {
    Garage testGarage = new Garage();
    testGarage.setId("630ca281f12905d5f5249f08");
    testGarage.setCarModel("Shelby Cobra");
    testGarage.setHP(485);
    testGarage.setYear(1965);
    testGarage.setDesigner("Carroll Shelby");

    Garage savedGarage = garageRepository.save(testGarage);

    String testedGarage = savedGarage.getCarModel();

    Optional<Garage> garages = garageRepository.findByCarModel("Shelby Cobra");
    assertEquals(testedGarage, garages.toString());
}

我对单元测试和MongoDB非常陌生,所以我不确定这个错误发生的位置和原因。我跳过了添加控制器,因为我认为其余的代码就足够了。

bvjveswy

bvjveswy1#

在我看来,garageRepository被示例化为一个模拟,所以save方法根本不知道要返回什么,默认情况下返回空值。如果调用save()mMethod,您必须告诉Mockito返回什么。这可以通过Mockito.when(...).thenReturn(...)来实现。

您的测试应该测试服务,但您没有调用服务的任何一个方法!

另一方面,在存储库中查询保存的对象是没有意义的,因为对象实际上没有保存(同样,存储库是模拟的,您想要测试服务,所以您想要确保存储库的保存方法被正确调用)。相反,您应该验证save()方法的调用是否类似

Mockito.verify(garageRepository).save(testGarage);

...或者如果由于具有相同ID的现有对象而出现异常。尝试以下代码(未测试!):

@DisplayName("Garage Service Test")
@DataMongoTest
class GarageServiceTest {

@Mock
private GarageRepository garageRepository;
private GarageService garageService;

@BeforeEach
void setUp() {
    MockitoAnnotations.openMocks(this);
    //This would be the way to make the mock return sth., 
    //but not really   needed
    //Garage returnObject = new Garage();
    //returnObject.setId("630ca281f12905d5f5249f08");
    //returnObject.set...(...);
    //Mockito.when(garageRepository.save(Mockito.ANY))
    //   .thenReturn(returnObject);
    garageService = new GarageService(garageRepository);
}

@Test
@DisplayName("Add Car To Garage Test")
//This is the 'positive test, object isn't persisted yet
void testAddToGarage() {
    Garage testGarage = new Garage();
    testGarage.setId("630ca281f12905d5f5249f08");
    testGarage.setCarModel("Shelby Cobra");
    testGarage.setHP(485);
    testGarage.setYear(1965);
    testGarage.setDesigner("Carroll Shelby");
    Mockito.when(garageRepository
    .findByCarModel(testGarage.getCarModel()))
    .thenReturn(Optional.empty());
    garageService.addToGarage(testGarage);
    Mockito.verify(garageRepository).save(testGarage);
}

@Test
@DisplayName("Add Car To Garage Test")
//This is the 'negative' test, the repository indicates that the object
//is already persisted
@Expected(IllegalStateException.class)
void testAddToGarageAlreadyPersisted() {
    Garage testGarage = new Garage();
    testGarage.setId("630ca281f12905d5f5249f08");
    testGarage.setCarModel("Shelby Cobra");
    testGarage.setHP(485);
    testGarage.setYear(1965);
    testGarage.setDesigner("Carroll Shelby");
    Mockito.when(garageRepository
    .findByCarModel(testGarage.getCarModel()))
    .thenReturn(Optional.of(testGarage));
    garageService.addToGarage(testGarage);
    Mockito.verify(garageRepository, Mockito.never()).save(testGarage);
}

}

相关问题