单元测试中Moq对象多场景使用引发System.ObjectDisposedException问题
问题分析与解决方案
问题根源
你的测试代码中,Moq模拟GetFileStreamAsync时始终返回同一个Stream实例,但生产代码里该方法每次调用都会新建MemoryStream。当Handle方法用using释放这个共享实例后,SaveReportWithResponse再次调用时拿到的是已被释放的流,因此抛出ObjectDisposedException。
解决办法
修改Moq的Setup逻辑,让每次调用GetFileStreamAsync都返回全新的Stream实例,对齐生产代码的行为:
方案1:根据入参动态生成新流
完全复刻生产代码逻辑,每次调用都基于传入的base64字符串创建新的MemoryStream:
storageManager .Setup(m => m.GetFileStreamAsync(It.IsAny<string>())) .Returns((string fileName) => Task.FromResult<Stream>(new MemoryStream(Convert.FromBase64String(fileName))) );
方案2:复用固定字节数组生成新流
如果测试需要固定的流内容,可预先准备字节数组,每次调用都用它创建新的MemoryStream(原字节数组不会被Dispose操作影响):
// 预先定义测试用的字节数组 byte[] testContentBytes = Convert.FromBase64String("你的测试base64内容"); storageManager .Setup(m => m.GetFileStreamAsync(It.IsAny<string>())) .Returns(() => Task.FromResult<Stream>(new MemoryStream(testContentBytes)));
为什么移除using无效?
移除Handle中的using只是暂时避免第一次释放流,但这不符合生产代码的资源释放规范,更关键的是没有解决测试模拟与实际逻辑不一致的核心问题——生产代码每次调用都会生成新流,测试却复用同一个实例,这种差异会导致测试结果失真。
内容的提问来源于stack exchange,提问作者ladsaylee
相关产品推荐
相关产品推荐

