首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSubstitute模拟扩展方法

NSubstitute模拟扩展方法
EN

Stack Overflow用户
提问于 2015-02-24 10:46:12
回答 4查看 19.7K关注 0票数 16

我想做模拟扩展方法,但是它不起作用。这是如何做到的呢?

代码语言:javascript
复制
public static class RandomExtensions
{
    public static IEnumerable<int> NextInt32s(this System.Random random, int neededValuesNumber, int minInclusive, int maxExclusive)
    {
        // ...
    }
}
代码语言:javascript
复制
[Fact]
public void Select()
{
    var randomizer = Substitute.For<DefaultRandom>();
    randomizer.NextInt32s(3, 1, 10).Returns(new int[] { 1, 2, 3 });
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-02-24 23:11:27

NSubstitute不能按照Sriram的注释模拟扩展方法,但仍然可以将模拟的参数传递给扩展方法。

在本例中,Random类具有虚拟方法,因此我们可以直接使用NSubstitute和其他基于DynamicProxy的模拟工具来模拟它。(特别是对于NSubstitute,我们需要非常小心地模拟类。请阅读文献资料中的警告。)

代码语言:javascript
复制
public static class RandomExtensions {
    public static IEnumerable<int> NextInt32s(this System.Random random, int neededValuesNumber, int minInclusive, int maxExclusive) { /* ... */ }
}
public class RandomExtensionsTests {
    [Test]
    public void Select()
    {
        const int min = 0, max = 10;
        var randomizer = Substitute.For<Random>();
        randomizer.Next(min, max).Returns(1, 2, 3);

        var result = randomizer.NextInt32s(3, 0, 10).ToArray();

        Assert.AreEqual(new[] {1, 2, 3}, result);
    }
}
票数 3
EN

Stack Overflow用户

发布于 2015-02-25 13:53:07

是的,如果您创建一个接口(如IRandom ),并且扩展接口而不是实际的实现,您可以进行模拟。然后,您应该能够在您的测试类中模拟接口。

代码语言:javascript
复制
public interface IRandom
{   
}

public class Random : IRandom
{     
}

public static class RandomExtensions
{
    public static string NextInt32s(
        this IRandom random, 
        int neededValuesNumber, 
        int minInclusive, 
        int maxExclusive)
    {
    }
}

在您的测试类中添加:

代码语言:javascript
复制
IRandom randomizer = Substitute.For<IRandom>();
var result = randomizer.NextInt32s(3,0,10);

通过这个过程,您只是在模拟接口,而不是实际的类。

票数 0
EN

Stack Overflow用户

发布于 2019-08-19 12:21:47

作为对其他答案的扩展,下面是我如何绕过它的方法。

假设有一个接口IDoStuff,还有一个扩展IDoStuff的库。您有一个实现MyClass的类IDoStuff,并且在某个地方有人对接口使用扩展方法。看起来是这样的;

代码语言:javascript
复制
using System;

interface IDoStuff
{
    string SayHello();
}

class MyClass : IDoStuff
{
    public string SayHello()
    {
        return "Hello";
    }
}

// somewhere someone wrote an extension method for IDoStuff

static class DoStuffExtensions
{
    static string SayHelloToBob(this IDoStuff other)
    {
        return other.SayHello() + " Bob";
    }
}

class UserOfIDoStuff
{
    void UseIDoStuff(IDoStuff incoming)
    {
        Console.WriteLine(incoming.SayHelloToBob());
    }
}

您想要模拟IDoStuff,但不能模拟扩展方法SayHelloToBob。您可以做的是创建另一个实现IDoStuff但也包括SayHelloToBob的接口。

代码语言:javascript
复制
interface IDoStuffWithExtensions : IDoStuff
{
    string SayHelloToBob();
}

class MyClass : IDoStuffWithExtensions
{
    public string SayHello()
    {
        return "Hello";
    }

    // Wrap / internalise the extension method
    public string SayHelloToBob()
    {
        return DoStuffExtensions.SayHelloToBob(this);
    }
}

class UserOfIDoStuff
{
    void UseIDoStuff(IDoStuffWithExtensions incoming)
    {
        Console.WriteLine(incoming.SayHelloToBob());
    }
}

现在,您可以愉快地模拟IDoStuffWithExtensions了。

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

https://stackoverflow.com/questions/28693698

复制
相关文章

相似问题

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