.net - 如何使用 Moq 测试 lambda 函数?

标签 .net unit-testing mocking lambda moq

有一个功能:

public class MyCacheClass : ICache
{
    public void T GetObject<T>(Func<T> func)
    {
        T t;
        ...
        t = func();
        ...
        return t;
    }
}

public class MyWorkClass : IWork
{
    public Object MyWorkMethod(string value)
    {
        return new object();
    }
}

这些函数的调用方式如下:
public class MyTestableClass 
{
    public void MyTestableFunc(ICache cache, IWorkClass work)
    {
        string strVal="...";
        ...
        Object obj = cache(()=>work.MyWorkMethod(strVal));
        ...
    }
}

有必要为此编写一个 UnitTest(带 Moq)并检查是否将正确的参数传递给“MaCacheClass.GetObject”。

它应该是这样的:
[TestMethod]
public void MyTest()
{
    Mock<ICache> mockCache = new Mock<ICache>();
    Mock<IWorkClass> mockWorkClass  = new Mock<IWorkClass>();

    MyTestableClass testable = new MyTestableClass();
    testable.MyTestableFunc(mockCache.Object, mockWorkClass.Object);

    // should I check if 'MyCacheClass' was called with proper parameter?
    mockCache.Verify(mock=>mock.GetObject(...)).Times.Once());
}

我如何提供适合“lambda 函数”的参数?
还有其他选择吗?

欢迎任何想法。

最佳答案

选项之一可能是:而不是在 Funct 参数上传递一些实现与“GetObject”函数接口(interface)的对象,例如:

public interface IGetObject
{
    T GetObject<T>();
}

public class MyGetObject : IGetObject
{
    public MyGetObject()
    {
    }

    public void Init(string strVal, Func<string, T> func)
    {
        _strVal = strVal;
        _func = func;
    }

    public T GetObject<T>()
    {
        return _func(_strVal);
    }
}

public class MyCacheClass : ICache
{
    public void T GetObject<T>(IGetObject getter)
    {
        T t;
        ...
        t = getter.GetObject<T>();
        ...
        return t;
    }
}

public class MyTestableClass 
{
    public void MyTestableFunc(ICache cache, IWorkClass work)
    {
        string strVal="...";
        IGetObject getter = UnityContainer.Resolve<IGetObject>();
        getter.Init(strVal, str=>work.MyWorkMethod(str));
        ...
        Object obj = cache.GetObject(getter);
        ...
    }
}

在这种情况下,我想,我们还需要将 UnityContainer 注入(inject)到测试对象中,因此它将是这样的:
[TestMethod]
public void MyTest()
{
    Mock<ICache> mockCache = new Mock<ICache>();
    Mock<IWorkClass> mockWorkClass  = new Mock<IWorkClass>();
    Mock<IGetObject> mockGetter  = new Mock<IGetObject>();

    mockGetter.Setup(mock=>mock.GetObject()).Return(new Object());

    MyTestableClass testable = new MyTestableClass();
    testable.MyTestableFunc(mockCache.Object, mockWorkClass.Object);

    // should I check if 'MyCacheClass' was called with proper parameter?
    mockCache.Verify(mock=>mock.GetObject(mockGetter.Object)).Times.Once());
}

并为“MyCacheClass”的“GetObject”方法提供额外的测试,以检查它是否调用 IGetObject 参数的“GetObject”方法......

附言有点复杂的解决方案......所以,如果有人看到更好的解决方案,请指教!

关于.net - 如何使用 Moq 测试 lambda 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3752565/

相关文章:

c# - 模型将集合属性与局部 View 绑定(bind)

javascript - 为什么我必须在 beforeEach() 中调用 spyOn?

python - 我如何在我的 Django 应用程序中模拟一个到达外部服务的组件?

python - 单元测试 Python : Mocking function calls inside function

python - 如何测试在对象实例化期间创建的函数?

.net - 如何使用signtool.exe对CAB文件进行签名?

c# - 如何在不卸载旧服务的情况下测试新版本的windows服务

c# - 为什么 IEnumerable 上没有 ForEach 扩展方法?

postgresql - 如何在无法迁移表的情况下对 Laravel 应用程序进行单元测试,因为迁移是由另一个应用程序处理的

java - 下载单元测试