[英]Rhinomocks - Mocking delegates
public interface IServiceInvoker
{
R InvokeService<T, R>(Func<T, R> invokeHandler) where T : class;
}
public class MediaController : Controller
{
private IServiceInvoker _serviceInvoker;
public MediaController(IServiceInvoker serviceInvoker)
{
_serviceInvoker = serviceInvoker;
}
public JsonResult GetAllMedia()
{
var media = _serviceInvoker.InvokeService<IMediaService, List<MediaBase>>(proxy => proxy.GetAllMediaInJson());
JsonResult jsonResult = new JsonResult();
jsonResult.Data = media;
jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return jsonResult;
}
[TestClass]
public class MediaControllerTests
{
[TestMethod]
public void GetAllMedia()
{
JsonResult data;
var serviceInvoker = MockRepository.GenerateStub<IServiceInvoker>();
var media = CreateSeveralMedia();
serviceInvoker.Stub(c => c.InvokeService<IMediaService, List<MediaBase>>(p => p.GetAllMediaInJson())).Return(media);
data = new MediaController(serviceInvoker).GetAllMedia();
serviceInvoker.VerifyAllExpectations();
Assert.IsNotNull(data);
}
} }
I am stubbing the service and returning a collection. 我正在对服务进行存根并返回一个集合。 When I run this test, media is null.
当我运行此测试时,媒体为空。 Any idea, how can I set expectations on this mock ?
任何想法,我如何设定这个模拟的期望?
Just found a solution. 刚刚找到了解决方案。 It seems to be a little ugly, but it is the first iteration only probably more elegant version will appear soon.
它似乎有点难看,但它是第一次迭代,可能很快就会出现更优雅的版本。 The idea is to create another stub and match
Func<>
against it: I will provide code for my use case: 我的想法是创建另一个存根并匹配它的
Func<>
:我将为我的用例提供代码:
[Theory]
[InlineData(342, 31129, 3456)]
public void should_call_service_invoker_and_return_result(int number1, int number2, int expected)
{
var calculator = MockRepository.GenerateStub<ICalculator>();
calculator.Stub(_ => _.Add(number1, number2)).Return(expected);
var serviceInvoker = MockRepository.GenerateStub<ServiceInvoker<ICalculator>>();
serviceInvoker
.Stub(_ => _.Invoke(Arg<Func<ICalculator, int>>.Matches(d => d(calculator) == calculator.Add(number1, number2))))
.Return(expected);
var serviceConsumer = new ServiceConsumer(serviceInvoker);
var actual = serviceConsumer.GetAddResultFor(number1, number2);
Assert.Equal(expected, actual);
}
xUnit + extensions is used as testing framework. xUnit +扩展用作测试框架。 Please ignore
Theory
and InlineData
stuff -- it is just another way to get rid of unnecessary test setup. 请忽略
Theory
和InlineData
东西 - 它只是摆脱不必要的测试设置的另一种方法。
Here is the code of SUT: 这是SUT的代码:
public class ServiceConsumer
{
private readonly ServiceInvoker<ICalculator> serviceInvoker;
public ServiceConsumer(ServiceInvoker<ICalculator> serviceInvoker)
{
this.serviceInvoker = serviceInvoker;
}
public int GetAddResultFor(int number1, int number2)
{
return serviceInvoker.Invoke(_ => _.Add(number1, number2));
}
}
public class ServiceInvoker<T>
{
public virtual R Invoke<R>(Func<T, R> func)
{
throw new NotImplementedException();
}
}
public interface ICalculator
{
int Add(int number1, int number2);
}
Hope this will be helpful. 希望这会有所帮助。 Any suggestions of how to add more beauty are welcome :)
欢迎任何有关如何添加更多美容的建议:)
The lambda in your unit test compiles into a class-level method (a method inside your unit test). 单元测试中的lambda编译为类级方法(单元测试中的方法)。 Inside your controller, a different lambda compiles into a class-level method (inside the controller).
在你的控制器中,一个不同的lambda编译成一个类级方法(在控制器内部)。 The stub set up in your unit test doesn't match the stub being executed in your controller, so Rhino Mocks returns a default (null).
单元测试中设置的存根与控制器中执行的存根不匹配,因此Rhino Mocks返回默认值(null)。 More here: http://groups.google.com/group/rhinomocks/browse_frm/thread/a33b165c16fc48ee?tvc=1
更多信息: http : //groups.google.com/group/rhinomocks/browse_frm/thread/a33b165c16fc48ee?tvc = 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.