You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:26:27