如何Mock CsvConfiguration?CSVHelper服务测试遇空引用异常
问题:如何Mock CSVHelper构造函数中的CsvConfiguration?
生产代码:
{ private readonly CsvConfiguration _csvConfig; public CsvWriterService(CsvConfiguration csvConfig) { _csvConfig = csvConfig; } public void WriteCsv(TradeRecord record, string filePath) { using var writer = new StreamWriter(filePath); using var csv = new CsvWriter(writer, _csvConfig); csv.Context.RegisterClassMap<TradeRecordMap>(); csv.WriteHeader<TradeRecord>(); csv.WriteRecord(record); } }
测试代码及问题:
private readonly CsvConfiguration _csvConfig; private CsvWriterService CsvWriterService_Sut; public CsvWriterServiceTest() { CsvWriterService_Sut = new CsvWriterService(_csvConfig); } [Fact] public void WriteCsv_RecordsAndFilePath_Should_WriteCsv() { //Arrange var date = new DateTime(2021, 1, 1); var records = new List<TradeRecord>{}; var filePath = "TestFilePath.csv"; //Act CsvWriterService_Sut.WriteCsv(records, filePath); //Assert Assert.True(File.Exists(filePath)); }
运行测试时出现NullReferenceException,原因是_csvConfig未初始化,导致CsvWriterService_Sut实例化失败;同时测试代码中WriteCsv的参数类型与方法定义不匹配(方法接收单个TradeRecord,测试传了List<TradeRecord>)。
解决方案
1. 无需Mock CsvConfiguration
CsvConfiguration是纯配置类,无外部依赖,直接实例化真实对象即可,不需要Mock。实例化时指定文化信息(如InvariantCulture)即可满足基本需求。
2. 修正测试代码错误
- 初始化
CsvConfiguration实例,避免null - 修正
WriteCsv的参数类型,匹配方法定义 - 使用临时文件路径,避免测试后残留文件、避免路径冲突
修正后的测试代码
private CsvWriterService CsvWriterService_Sut; public CsvWriterServiceTest() { // 初始化CsvConfiguration,指定文化信息 var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture); CsvWriterService_Sut = new CsvWriterService(csvConfig); } [Fact] public void WriteCsv_RecordAndFilePath_Should_WriteCsv() { // Arrange // 填充TradeRecord的必要属性 var testRecord = new TradeRecord { Date = new DateTime(2021, 1, 1) // 其他属性按需填充 }; // 生成唯一临时文件路径 var filePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.csv"); try { // Act CsvWriterService_Sut.WriteCsv(testRecord, filePath); // Assert Assert.True(File.Exists(filePath)); // 可选:验证文件内容正确性,比如检查表头是否存在 var content = File.ReadAllText(filePath); Assert.Contains(nameof(TradeRecord.Date), content); } finally { // 清理临时文件 if (File.Exists(filePath)) { File.Delete(filePath); } } }
补充:自定义配置
如果需要特殊配置(比如分隔符、引用字符),实例化时直接设置即可:
var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture) { Delimiter = ";", Quote = '\'' };
内容的提问来源于stack exchange,提问作者Doraemon
相关产品推荐
相关产品推荐

