Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Moq模拟Fluent接口_C#_Unit Testing_Moq_Fluent - Fatal编程技术网

C# 使用Moq模拟Fluent接口

C# 使用Moq模拟Fluent接口,c#,unit-testing,moq,fluent,C#,Unit Testing,Moq,Fluent,我已经看了很多关于这个主题的问题,但是没有一个能解决我所面临的问题 我有一些代码看起来有点像这样 IBaseDataCollector<MyClass> myDataCollector; myDataCollector = new Mock<IBaseDataCollector<MyClass>>(); systemUnderTest = new Thing(myDataCollector.Object); 其中SomeMethod()和SomeSeco

我已经看了很多关于这个主题的问题,但是没有一个能解决我所面临的问题

我有一些代码看起来有点像这样

IBaseDataCollector<MyClass> myDataCollector;

myDataCollector = new Mock<IBaseDataCollector<MyClass>>();

systemUnderTest = new Thing(myDataCollector.Object);
其中
SomeMethod()
SomeSecondMethod()
都返回
this
(即
myDataCollector的实例)

当我运行测试时,我在调用
myDataCollector
的地方得到一个
NullReferenceException

我试着在我的测试设置中添加这个

myDataCollector.Setup(_=> _.SomeMethod()),Returns(myDataCollector.Object);
但它甚至无法编译,抱怨它“无法解析方法‘Returns(acollector)’”

现在,如果我重构我的
东西
类来阅读

myDataCollector.SomeMethod();
myDataCollector.SomeSecondMethod()
var collection = myDataCollector.GetData();
我的测试执行正常

如果是这样的话,我只需要重构我的代码,继续生活,但实际上,我需要在
SelectMany
call中调用我的代码

var collection = list.SelectMany(_=> myDataCollector.SomeMethod()
                     .SomeSecondMethod(_)
                     .GetData());
同样,我知道我可以用
ForEach
替换
SelectMany
,并用调用
GetData()
的每次迭代结果手动填充集合,这样我就可以去掉调用中的fluent元素,但这意味着重构代码只是为了让测试工作,这感觉不对


我应该如何在模拟对象上调用
Setup()
,以使我的流畅调用正常工作?

看看下面的测试代码(我发明了一些细节来填补空白)。模拟对象实例应该作为一个值从它自己的方法返回,如图所示

    public class UnitTestExample
    {

        [Fact]
        public void UnitTestExample1()
        {
            var myClassInterfaceMock = new Mock<IInterface<MyClass>>();
            var instance = myClassInterfaceMock.Object;
            var myList = new List<MyClass>()
            {
                new MyClass() { Attribute = 1 }
            };

            myClassInterfaceMock.Setup(_ => _.SomeMethod()).Returns(instance);
            myClassInterfaceMock.Setup(_ => _.SomeSecondMethod()).Returns(instance);
            myClassInterfaceMock.Setup(_ => _.GetData()).Returns(myList);

            var myDependentClass = new MyDependentClass(instance);
            var result = myDependentClass.DoTheThing();

            Assert.True(result.Count.Equals(1));
        }
    }

    public interface IInterface<T>
    {
        IInterface<T> SomeMethod();
        IInterface<T> SomeSecondMethod();
        List<T> GetData();
    }

    public class MyClass
    {
        public int Attribute { get; set; }
    }

    public class MyDependentClass
    {
        private readonly IInterface<MyClass> _test;

        public MyDependentClass(IInterface<MyClass> test)
        {
            _test = test;
        }

        public List<MyClass> DoTheThing()
        {
            return _test.SomeMethod().SomeSecondMethod().GetData();
        }
    }
公共类单元测试示例
{
[事实]
public void UnitTestExample1()
{
var myClassInterfaceMock=new Mock();
var instance=myClassInterfaceMock.Object;
var myList=新列表()
{
新建MyClass(){Attribute=1}
};
myClassInterfaceMock.Setup(\u=>\ u0.SomeMethod())。返回(实例);
myClassInterfaceMock.Setup(\u=>\ u0.SomeSecondMethod())。返回(实例);
myClassInterfaceMock.Setup(\u=>\ u0.GetData()).Returns(myList);
var myDependentClass=新的myDependentClass(实例);
var result=myDependentClass.DoTheThing();
Assert.True(result.Count.Equals(1));
}
}
公共接口接口
{
i接口方法();
i接口SomeSecondMethod();
List GetData();
}
公共类MyClass
{
公共int属性{get;set;}
}
公共类MyDependentClass
{
专用只读接口测试;
公共MyDependentClass(接口测试)
{
_测试=测试;
}
公共列表DoTheThing()
{
返回_test.SomeMethod().SomeSecondMethod().GetData();
}
}

也许
SetReturnsDefault
会有所帮助。看看亚当,当我试着像你一样设置它时,我仍然得到“无法解决”的错误。然后我注意到在我的界面中,我的fluent调用返回的是
BaseDataCollector
,而不是
ibacollector
。也就是说,如果我真的找到了解决方案,如果没有你的努力,我会花更长的时间。非常感谢。很高兴它成功了!这感觉就像是在转移视线,有时你只需要另一双眼睛。干杯
    public class UnitTestExample
    {

        [Fact]
        public void UnitTestExample1()
        {
            var myClassInterfaceMock = new Mock<IInterface<MyClass>>();
            var instance = myClassInterfaceMock.Object;
            var myList = new List<MyClass>()
            {
                new MyClass() { Attribute = 1 }
            };

            myClassInterfaceMock.Setup(_ => _.SomeMethod()).Returns(instance);
            myClassInterfaceMock.Setup(_ => _.SomeSecondMethod()).Returns(instance);
            myClassInterfaceMock.Setup(_ => _.GetData()).Returns(myList);

            var myDependentClass = new MyDependentClass(instance);
            var result = myDependentClass.DoTheThing();

            Assert.True(result.Count.Equals(1));
        }
    }

    public interface IInterface<T>
    {
        IInterface<T> SomeMethod();
        IInterface<T> SomeSecondMethod();
        List<T> GetData();
    }

    public class MyClass
    {
        public int Attribute { get; set; }
    }

    public class MyDependentClass
    {
        private readonly IInterface<MyClass> _test;

        public MyDependentClass(IInterface<MyClass> test)
        {
            _test = test;
        }

        public List<MyClass> DoTheThing()
        {
            return _test.SomeMethod().SomeSecondMethod().GetData();
        }
    }