Mock JavaScriptDeserializer报错,求基于Wrapper的正确Mock实现方案
解决JavaScriptSerializer的Moq问题:正确的Wrapper实现与Mock步骤
首先,我得先指出你当前Wrapper代码里的一个小问题——你的Deserialize方法里调用了serializer.Deserialize<T>(data),但方法本身并没有定义泛型参数T,而且接口IJavaScriptSerializerWrapper的方法定义也需要对应调整,不然代码根本跑不起来。咱们先把这个Wrapper修正确,再一步步实现Mock。
第一步:修正Wrapper接口与实现
首先定义一个合理的接口,包含泛型和非泛型的反序列化方法(按需选择):
public interface IJavaScriptSerializerWrapper { // 泛型反序列化方法,最常用 T Deserialize<T>(string data); // 非泛型版本,如果需要根据Type动态反序列化的话 object Deserialize(string data, Type targetType); }
然后实现这个Wrapper,这里建议把JavaScriptSerializer实例化放到构造函数里,后续如果要扩展也更灵活:
public class JavaScriptSerializerWrapper : IJavaScriptSerializerWrapper { private readonly JavaScriptSerializer _serializer; public JavaScriptSerializerWrapper() { _serializer = new JavaScriptSerializer(); } public T Deserialize<T>(string data) { return _serializer.Deserialize<T>(data); } public object Deserialize(string data, Type targetType) { return _serializer.Deserialize(data, targetType); } }
第二步:正确实现Moq单元测试
你之前直接MockJavaScriptSerializer报错的原因很简单:Moq只能Mock接口或者带有virtual/abstract修饰的类方法,而JavaScriptSerializer的Deserialize方法是非virtual的具体方法,所以直接Mock会失败——这也是你做Wrapper的核心原因,思路是对的!
下面是完整的测试代码示例:
using Moq; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] public class YourTargetTestClass { // 声明Mock对象 private Mock<IJavaScriptSerializerWrapper> _jsSerializerMock; // 假设这是你要测试的类,它依赖IJavaScriptSerializerWrapper private YourClassUnderTest _classUnderTest; [TestInitialize] public void TestInitializer() { // 初始化Mock实例 _jsSerializerMock = new Mock<IJavaScriptSerializerWrapper>(); // 将Mock的实例注入到被测类中(这里假设被测类通过构造函数依赖注入) _classUnderTest = new YourClassUnderTest(_jsSerializerMock.Object); } [TestMethod] public void WhenDeserializingJson_ShouldReturnExpectedObject() { // 1. 准备测试数据 var testJson = "{\"Id\":1,\"Name\":\"SampleData\"}"; var expectedModel = new YourDataModel { Id = 1, Name = "SampleData" }; // 2. 设置Mock的行为:当调用Deserialize<YourDataModel>并传入testJson时,返回预期对象 _jsSerializerMock .Setup(serializer => serializer.Deserialize<YourDataModel>(testJson)) .Returns(expectedModel); // 3. 执行被测方法 var result = _classUnderTest.MethodThatUsesDeserialization(testJson); // 4. 验证结果是否符合预期 Assert.AreEqual(expectedModel.Id, result.Id); Assert.AreEqual(expectedModel.Name, result.Name); // 可选:验证Mock的方法是否被调用了一次(确保被测逻辑确实用到了Wrapper) _jsSerializerMock .Verify(serializer => serializer.Deserialize<YourDataModel>(testJson), Times.Once); } }
关键注意点
- 确保接口和Wrapper的方法签名完全匹配,特别是泛型参数的定义
- 被测类要通过依赖注入的方式接收
IJavaScriptSerializerWrapper,而不是在内部直接实例化JavaScriptSerializerWrapper,这样才能替换成Mock对象 - 如果需要模拟反序列化异常的场景,可以用
Throws方法:_jsSerializerMock .Setup(serializer => serializer.Deserialize<YourDataModel>(It.IsAny<string>())) .Throws(new InvalidOperationException("Invalid JSON"));
内容的提问来源于stack exchange,提问作者Neha Kansara
相关产品推荐
相关产品推荐

