【问题标题】:Java - Spring and Mockito - Mocking a constructor parameter that is not a field in class?Java - Spring 和 Mockito - 模拟不是类中字段的构造函数参数?
【发布时间】:2022-11-17 03:03:12
【问题描述】:

我有以下 Spring 组件,我正在尝试对其进行单元测试:

@Component
public class OrderService {

    private final DatabaseConnection dbConnection;
    private final String collectionName;

    @Autowired
    public OrderService(
            DatabaseConnection dbConnection,
            DatabaseConfig databaseConfig) {

        this.dbConnection = dbConnection;
        this.collectionName = databaseConfig.getCollectionName();
    }
    
    //methods etc...
    
    }

DatabaseConfig类如下:

@ConfigurationProperties(prefix = "database")
@ConstructorBinding
public class DatabaseConfig {

    //methods etc...
}

我正在尝试在我的 OrderService 类中注入模拟,如下所示:

@RunWith(MockitoJUnitRunner.class)
class OrderServiceTest {

    @InjectMocks
    OrderService orderService;

    @Mock
    DatabaseConnection dbConnection; // working as expected
    @Mock
    DatabaseConfig databaseConfig; // giving null pointer
    @Mock
    DatabaseCollectionConfig databaseCollectionConfig;

    @BeforeEach
    public void setup() {
        MockitoAnnotations.openMocks(this);

        when(databaseConfig.getCollections()).thenReturn(databaseCollectionConfig);
        when(databaseCollectionConfig.getCollectionName()).thenReturn("myCollection");

    }

当我运行我的测试课时,我得到:

org.mockito.exceptions.misusing.InjectMocksException: 
Cannot instantiate @InjectMocks field named 'OrderService' of type 'class com.my.package.OrderService'.
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : null

问题是在 OrderService 构造函数中,当我调试此行时,该行显示为 null:

 this.collectionName = databaseConfig.getCollectionName();

我怎样才能正确地模拟databaseConfig.getCollectionName() 来解决 null 问题?

【问题讨论】:

    标签: java spring junit mockito junit-runner


    【解决方案1】:

    嘲笑行为, 不是价值观. @ConfigurationProperties 类只是数据的容器;它没有(一般来说)任何事物。使用您的测试值(例如,setCollections(testDatabaseCollectionConfig))用new创建一个真实的。

    【讨论】:

      【解决方案2】:

      您可以尝试为该方法创建一个模拟并创建一个对象实例,而不是使用 InjectMocks 注释。

      @RunWith(MockitoJUnitRunner.class)
      class OrderServiceTest {
      
          OrderService orderService;
      
          @Mock
          DatabaseConnection dbConnection; // working as expected
          @Mock
          DatabaseConfig databaseConfig; // giving null pointer
          @Mock
          DatabaseCollectionConfig databaseCollectionConfig;
      
          @BeforeEach
          public void setup() {
        
              (...)
        
              when(databaseConfig.getCollections()).thenReturn(databaseCollectionConfig);
              when(databaseCollectionConfig.getCollectionName()).thenReturn("myCollection");
              orderService = new OrderService(dbConnection, databaseConfig);
      
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-28
        • 1970-01-01
        • 2022-10-15
        相关资源
        最近更新 更多