Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.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# 通过设置设置设置模拟属性会导致';表达式不是方法调用';_C#_.net_Mocking_Moq - Fatal编程技术网

C# 通过设置设置设置模拟属性会导致';表达式不是方法调用';

C# 通过设置设置设置模拟属性会导致';表达式不是方法调用';,c#,.net,mocking,moq,C#,.net,Mocking,Moq,我有下面的代码,其中我的模拟接口有一个Recorder属性,它是一个类 然后,我尝试在该类上设置一个属性,但得到的表达式不是方法调用错误。你能帮忙吗 在运行时尝试设置枚举属性时出错。它会抛出具有以下堆栈跟踪的ArgumentException: at Moq.ExpressionExtensions.ToMethodCall(LambdaExpression expression) at Moq.Mock.<>c__DisplayClass1c`2.<Setup>b

我有下面的代码,其中我的模拟接口有一个Recorder属性,它是一个类

然后,我尝试在该类上设置一个属性,但得到的
表达式不是方法调用
错误。你能帮忙吗

在运行时尝试设置枚举属性时出错。它会抛出具有以下堆栈跟踪的ArgumentException:

at Moq.ExpressionExtensions.ToMethodCall(LambdaExpression expression)
   at Moq.Mock.<>c__DisplayClass1c`2.<Setup>b__1b()
   at Moq.PexProtector.Invoke[T](Func`1 function)
   at Moq.Mock.Setup[T,TResult](Mock mock, Expression`1 expression, Func`1 condition)
   at Moq.Mock`1.Setup[TResult](Expression`1 expression)
在Moq.ExpressionExtensions.ToMethodCall(LambdaExpression表达式)处
在Moq.Mock.c_uuu显示Class1C`2.b_uuu1b()
在Moq.PexProtector.Invoke[T](Func`1函数)
在Moq.Mock.Setup[T,TResult](模拟模拟,表达式'1表达式,函数'1条件)
在Moq.Mock`1.Setup[TResult](表达式`1表达式)
谢谢

//Works
var mock = new Moq.Mock<IEngine>(); 
//Works
mock.Setup(x => x.Recorder).Returns(new Moq.Mock<Recorder>().Object);  
//Fails on the next line assigning a property value!!!
mock.Setup(x => x.Recorder.RunState).Returns(Recorder.eRunStates.Play);  
//有效
var mock=新的Moq.mock();
//工作
Setup(x=>x.Recorder).Returns(新的Moq.mock().Object);
//在下一行指定属性值失败!!!
mock.Setup(x=>x.Recorder.RunState).Returns(Recorder.eRunStates.Play);

更新-我发现RunState不是一个属性,而是一个字段/成员,它是一个枚举

我认为您应该返回您在第一部分中为第二部分创建的模拟:

var mockRecorder = new Moq.Mock<Recorder>();
mock.Setup(x => x.Recorder).Returns(mockRecorder.Object);
mockRecorder.Setup(x => x.RunState).Returns(Recorder.eRunStates.Play);

您需要在模拟对象上进行设置,以配置RunState属性

var mockRecorder = new Mock<Recorder>();
mockRecorder.Setup(x => x.RunState).Returns(eRunStates.Play);

mock.Setup(x => x.Recorder).Returns(mockRecorder.Object);
var mockRecorder=new Mock();
mockRecorder.Setup(x=>x.RunState).Returns(eRunStates.Play);
Setup(x=>x.Recorder).Returns(mockRecorder.Object);
编辑:仅供参考,在访问.Object属性之前,您需要在模拟上进行所有设置,因为此时已创建对象,无法进行进一步的设置


另外,还有几点建议,看起来运行状态的枚举嵌套在recorder类中,我会将它移到一个单独的类中&另外删除“e”前缀。

如果在模拟上使用SetupGet而不是setup,这将起作用

var mockRecorder = new Moq.Mock<Recorder>();
mock.SetupGet(x => x.Recorder).Returns(mockRecorder.Object);
mockRecorder.SetupGet(x => x.RunState).Returns(Recorder.eRunStates.Play);
var mockRecorder=new Moq.Mock();
SetupGet(x=>x.Recorder).Returns(mockRecorder.Object);
SetupGet(x=>x.RunState).Returns(Recorder.eRunStates.Play);

我发现创建记录器的模拟,然后将值分配给模拟对象似乎可以解决这个问题。但不确定这是否是正确的做事方式

var mockRecorder = new Moq.Mock<Recorder>();
mockRecorder.Object.RunState = Recorder.eRunStates.Play;
var mockRecorder=new Moq.Mock();
mockRecorder.Object.RunState=Recorder.eRunStates.Play;

很遗憾,这会导致相同的错误。你说的假货是指手写的吗?@乔恩:是的。依赖被调用的特定属性感觉非常脆弱。这是令人讨厌的遗留代码,我快要放弃了honest@Jon:您尚未向我们提供有关此错误发生位置的详细信息。。。你能拿出一个简短但完整的程序来演示这个问题吗?你能告诉我们你从哪里得到的错误吗?它是编译时错误还是执行时错误,如果是执行时错误,它什么时候发生?那么哪个调用失败了?第一个调用还是第二个调用?(如果是第一个,让我们从图片中完全删除第二个…)同样的问题。我注意到它是一个字段而不是一个属性,因为我需要声明调用了IEngine中的一个方法,但这需要模拟并传递给另一个类。不确定是否可以模拟字段。你能将Recorder子类化并将其传入吗?我已经添加了一个答案,并直接在模拟对象上设置了字段,尽管我不确定这是否完全正确
var mockRecorder = new Moq.Mock<Recorder>();
mockRecorder.Object.RunState = Recorder.eRunStates.Play;