首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Moq模拟扩展方法?

如何使用Moq模拟扩展方法?
EN

Stack Overflow用户
提问于 2009-02-18 17:48:01
回答 6查看 78.9K关注 0票数 95

我正在写一个测试,它依赖于一个扩展方法的结果,但我不希望该扩展方法将来的失败也会破坏这个测试。模仿这一结果似乎是显而易见的选择,但Moq似乎没有提供一种覆盖静态方法(扩展方法的要求)的方法。Moq.Protected和Moq.Stub也有类似的想法,但它们似乎没有为这种情况提供任何东西。我是不是遗漏了什么,或者我应该以不同的方式来做这件事?

这里有一个简单的例子,它使用通常的"Invalid member on a non-overridable“失败。这是一个需要模拟扩展方法的坏例子,但它应该这样做。

代码语言:javascript
运行
复制
public class SomeType {
    int Id { get; set; }
}

var ListMock = new Mock<List<SomeType>>();
ListMock.Expect(l => l.FirstOrDefault(st => st.Id == 5))
        .Returns(new SomeType { Id = 5 });

对于任何可能建议我使用隔离器的TypeMock上瘾者,我很欣赏你的努力,因为看起来TypeMock可以蒙住眼睛喝醉了,但我们的预算不会很快增加。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-02-18 18:02:26

扩展方法只是伪装的静态方法。像Moq或Rhinomocks这样的模拟框架只能创建对象的模拟实例,这意味着模拟静态方法是不可能的。

票数 77
EN

Stack Overflow用户

发布于 2014-03-29 02:04:03

如果您可以更改扩展方法代码,则可以像这样编写代码,以便能够进行测试:

代码语言:javascript
运行
复制
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

public static class MyExtensions
{
    public static IMyImplementation Implementation = new MyImplementation();

    public static string MyMethod(this object obj)
    {
        return Implementation.MyMethod(obj);
    }
}

public interface IMyImplementation
{
    string MyMethod(object obj);
}

public class MyImplementation : IMyImplementation
{
    public string MyMethod(object obj)
    {
        return "Hello World!";
    }
}

因此,扩展方法只是实现接口的包装器。

(您可以只使用实现类,而不使用扩展方法,扩展方法是一种语法糖。)

您可以模拟implementation接口并将其设置为extensions类的实现。

代码语言:javascript
运行
复制
public class MyClassUsingExtensions
{
    public string ReturnStringForObject(object obj)
    {
        return obj.MyMethod();
    }
}

[TestClass]
public class MyTests
{
    [TestMethod]
    public void MyTest()
    {
        // Given:
        //-------
        var mockMyImplementation = new Mock<IMyImplementation>();

        MyExtensions.Implementation = mockMyImplementation.Object;

        var myClassUsingExtensions = new MyClassUsingExtensions();

        // When:
        //-------
        var myObject = new Object();
        myClassUsingExtensions.ReturnStringForObject(myObject);

        //Then:
        //-------
        // This would fail because you cannot test for the extension method
        //mockMyImplementation.Verify(m => m.MyMethod());

        // This is success because you test for the mocked implementation interface
        mockMyImplementation.Verify(m => m.MyMethod(myObject));
    }
}
票数 36
EN

Stack Overflow用户

发布于 2010-04-29 04:35:58

我知道这个问题一年来并不活跃,但微软发布了一个名为Moles的框架来解决这个问题。

下面是一些教程:

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/562129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档