Unit testing 颤振:moor中的单元测试dao
我第一次开始了单元测试。我正在学习的教程 这是我的测试代码,在这里我模拟我的dbManager类,但我不能模拟DAO,因为它们是在moor中自动生成的,并且没有setter方法Unit testing 颤振:moor中的单元测试dao,unit-testing,flutter,flutter-moor,Unit Testing,Flutter,Flutter Moor,我第一次开始了单元测试。我正在学习的教程 这是我的测试代码,在这里我模拟我的dbManager类,但我不能模拟DAO,因为它们是在moor中自动生成的,并且没有setter方法 class MockDbManager extends Mock implements DbManager{} void main() { RecipeLocalDataSource dataSource; MockDbManager _dbManager; setUp(() { _dbManage
class MockDbManager extends Mock implements DbManager{}
void main() {
RecipeLocalDataSource dataSource;
MockDbManager _dbManager;
setUp(() {
_dbManager = MockDbManager();
dataSource = RecipeLocalDataSource(_dbManager);
});
group('Search Food Table', (){
List<FoodTableData> getFoodTable(){
var list = [];
for(var i =1; i <=5 ; i++){
list.add(FoodTableData(id: i, name: 'item $i'));
}
return list;
}
var searchQuery = 'query';
test('Should return foodTableData when query is successful', (){
//arrange
when(_dbManager.foodTableDao.searchFoods(searchQuery)).thenAnswer((realInvocation) async => getFoodTable());
//act
var result = dataSource.searchFoodTable('test');
//assert
verify(_dbManager.foodTableDao.searchFoods(searchQuery));
expect(getFoodTable(), result);
});
});
}
我理解错误,但不知道如何解决
另外,我在preferenceManager类中也遇到了类似的问题,在这里我有一个UserPrefs的getter
UserPrefs get user => UserPrefs(_pref);
当我访问测试的
\u prefManager.user.name
时,它会抛出相同的错误。我怎样才能解决这个问题呢?我认为您缺少了一个级别的模拟,导致了空异常。请记住,模拟类对所有内容都返回null。你必须为每件事提供价值
您模拟了DbManager,但没有模拟DbManager中的foodTableDao字段
// I don't have your classes, so these are just my guesses at matching their interface
abstract class TableDao {
String searchFoods();
}
abstract class DbManager {
TableDao foodTableDao;
}
class MockDbManager extends Mock implements DbManager {}
class MockTableDao extends Mock implements TableDao {}
// ↑ Define this mocked class as well
void main() {
test('Mockito example', () {
final dbManager = MockDbManager();
final mockTableDao = MockTableDao();
// ↑ instantiate this mocked class which will be a field value inside dbManager
// Mock the field access for dbManager.foodTableDao
when(dbManager.foodTableDao).thenReturn(mockTableDao);
// ↑ You're missing this ↑ level of stubbing, so add this
when(mockTableDao.searchFoods()).thenAnswer((realInvocation) => 'Cucumber');
// ↑ define the stubbing at the mockTableDao level, not dbManger.mockTableDao.searchFoods
expect(dbManager.foodTableDao.searchFoods(), 'Cucumber');
// You can use foodTableDao field here, getting the mocked value as expected
});
}
在上面的示例中,您无法访问dbManager.foodTableDao
为dbManager.foodTableDao.searchFoods()
,因为在您对其进行模拟之前,dbManager.foodTableDao
为空。所以这一行:
when(_dbManager.foodTableDao.searchFoods(searchQuery)).thenAnswer((realInvocation) async => getFoodTable());
正在引发null异常,而不是下面的expect
测试。(从未达到预期测试。)
我猜,
\u prefManager.user.name
的问题与此相同。您需要模拟用户类并为_prefManager.User提供MockUser的when/return
,以便为\u prefManager.User.name
提供另一级别的when/return
就像是在嘲笑。。。你需要在模拟中再深入一层 代码是在编译时生成的,所以不确定在模拟代码时会遇到什么问题。它应该像正常的模拟一样工作。如果你能分享一个小样本,那么我可以研究一下。非常感谢你教我这个。你的解释很清楚,我一分钟就明白了我的错误:)我自己在为上面的答案编写测试代码时犯了同样的错误,所以我想我学到了和你一样多的东西。很高兴这有帮助:)
when(_dbManager.foodTableDao.searchFoods(searchQuery)).thenAnswer((realInvocation) async => getFoodTable());