Java - Spring和mock - mock构造函数参数不是类中的字段?



我有以下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构造函数中,当我调试这一行时,将显示为空:

this.collectionName = databaseConfig.getCollectionName();

如何正确模拟databaseConfig.getCollectionName()来解决null问题?

不需要使用@InjectMock注释,因为您在服务类中使用的是基于构造函数的注入。请像这样重写测试用例,然后再试一次。


@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);


}
}

您可以尝试为该方法创建一个模拟,并创建一个对象实例,而不是使用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);
}

模仿行为,而不是@ConfigurationProperties类只是数据的容器;(一般来说)不做任何事情。使用您的测试值(例如,setCollections(testDatabaseCollectionConfig))创建一个真正的new

最新更新