如何解决具有单一共享返回的最小起订量扩展设置
我想要做的是在模拟对象的多个方法调用上定义一个或多个Setup
(s)到一个Return
调用;因此避免多次调用执行 Setup().Return()
。
在尝试以下演示目标时,编译器提供错误,因此这不是实现该目标的合适方法。
var mPlatform = new Mock<IPlatformCommunicator>();
mPlatform.Setup(mp => mp.PreStart(It.IsAny<Action<IStatus>>()))
.Setup(mp => mp.Start(It.IsAny<Action<IStatus>>()))
...
.Returns(mockStatusIndeterminate.Object as IStatus);
有没有办法在 Setup
中定义多个方法调用以节省总代码行数?
这也不是一个选项:
.Setup(mp => mp.PreStart(It.IsAny<Action<IStatus>>()) || mp.Start(It.IsAny<Action<IStatus>>()))
解决方法
正如@Nkosi 提到的,不是真的。但根据您的使用情况,有些选项可能会起作用。
SetReturnsDefault
void Main()
{
var fooMock = new Mock<IFoo>();
fooMock.SetReturnsDefault<string>("This is a mocked value");
var foo = fooMock.Object;
Console.WriteLine($"foo.Bar(): {foo.Bar()}");
Console.WriteLine($"foo.Baz(): {foo.Baz()}");
}
public interface IFoo
{
string Bar();
string Baz();
}
任何返回字符串的方法都将返回您指定的任何内容。
- 默认值提供程序类似但全面。
void Main()
{
var fooMock = new Mock<IFoo>();
fooMock.DefaultValueProvider = new MyDefaultValueProvider();
var foo = fooMock.Object;
Console.WriteLine($"foo.Bar(): {foo.Bar()}");
Console.WriteLine($"foo.Baz(): {foo.Baz()}");
}
public interface IFoo
{
string Bar();
string Baz();
}
public class MyDefaultValueProvider : DefaultValueProvider
{
protected override object GetDefaultValue(Type type,Mock mock)
{
return "This is my default value";
}
}
- 创建您自己的扩展程序;以下是一个有效的 mvp
void Main()
{
var fooMock = new Mock<IFoo>();
fooMock.Setup(new Expression<Func<IFoo,string>>[] { x => x.Bar(),x => x.Baz() },"This is a mocked value");
var foo = fooMock.Object;
Console.WriteLine($"foo.Bar(): {foo.Bar()}");
Console.WriteLine($"foo.Baz(): {foo.Baz()}");
}
public interface IFoo
{
string Bar();
string Baz();
}
public static class MoqExtensions
{
public static Mock<T> Setup<T,U>(this Mock<T> self,Expression<Func<T,U>>[] setups,U returns)
where T : class
{
foreach (var setup in setups)
{
self.Setup(setup).Returns(returns);
}
return self;
}
}
以上所有产生以下结果
,您可以在 Mock<T>
上创建自己的扩展方法来满足您的需求:
public static class MoqExt {
public static void SetupReturnOnAll<T,TResult>(
this Mock<T> mock,TResult returnValue,params Expression<Func<T,TResult>>[] expressions)
where T: class {
foreach (var expr in expressions)
mock.Setup(expr).Returns(returnValue);
}
}
用法如下:
mPlatform
.SetupReturnOnAll(
mockStatusIndeterminate.Object as IStatus,mp => mp.PreStart(It.IsAny<Action<IStatus>>()),mp => mp.Start(It.IsAny<Action<IStatus>>()));
通过一些额外的努力可以改进界面:
mPlatform
.SetupAll(
mp => mp.PreStart(It.IsAny<Action<IStatus>>()),mp => mp.Start(It.IsAny<Action<IStatus>>()))
.Return(mockStatusIndeterminate.Object as IStatus);
为此你需要一个额外的类:
public class MultiSetup<T,TResult>
where T: class {
public Mock<T> Mock { get; }
public Expression<Func<T,TResult>>[] Expressions { get; }
public MultiSetup(Mock<T> mock,TResult>>[] expressions)
=> (Mock,Expressions) = (mock,expressions);
public void Return(TResult returnValue) {
foreach (var expr in Expressions)
Mock.Setup(expr).Returns(returnValue);
}
}
您可以使用此扩展程序创建它:
public static class MoqExt {
public static MultiSetup<T,TResult> SetupAll<T,TResult>>[] expressions)
where T : class
=> new MultiSetup<T,TResult>(mock,expressions);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。