我有一个接口和类看起来像这样:
public interface IServiceFacade
{
TResult Execute<TResult>(Func<IService, TResult> operation);
}
public class ServiceFacade : IServiceFacade
{
private readonly string endpoint = "EndPoint";
public TResult Execute<TResult>(Func<IService, TResult> operation)
{
// Call to remote WCF service that results in a TResult
return TResult;
}
}
IService
接口表示远程运行的WCF服务,因此该类中没有此接口的实现实例。
我这样称呼这个方法两次:
public class ServiceConsumer
{
public ServiceConsumer(IServiceFacade serviceFacade)
{
var returnInteger1 = serviceFacade.Execute(service => service.Method1("StringArgument1"));
var returnInteger2 = serviceFacade.Execute(service => service.Method1("StringArgument2"));
}
}
在我的单元测试中,我希望将第一个调用的返回值设为1,将第二个调用设为2。
示例testmethod
[Test]
public void TestMethod()
{
var serviceFacadeStub = MockRepository.GenerateStub<IServiceFacade>();
serviceFacadeStub.Stub(call => call.Execute(Arg<Func<IService, int>.Matches(?))).Return(1);
serviceFacadeStub.Stub(call => call.Execute(Arg<Func<IService, int>.Matches(?))).Return(2);
var sut = new ServiceConsumer(serviceFacadeStub);
}
我无法弄清楚要放入Matches
的内容,或者最好不要使用匹配以外的内容。
现在我正在使用RhinoMocks和NUnit但是如果有一个更好的框架来做这个我可以接受建议。
答案 0 :(得分:1)
在大多数情况下使用Func
/ Action
模拟方法有点棘手(在我知道的任何模拟框架中......)
通常你必须执行给定的Func
/ Action
,然后结果会影响被测单位的其余部分。
以下代码段显示了解决问题的简便方法:
[Test]
public void TestMethod(
{
var fakeService = MockRepository.GenerateStub<IService>();
fakeService.Stub(x => x.Method1("StringArgument1")).Return(1);
fakeService.Stub(x => x.Method1("StringArgument2")).Return(2);
var serviceFacadeStub = MockRepository.GenerateStub<IServiceFacade>();
serviceFacadeStub.Stub(call => call.Execute(Arg<Func<IService, int>>.Is.Anything))
.WhenCalled(invocation =>
{
var func = (Func<IService, int>)invocation.Arguments[0];
invocation.ReturnValue = func(fakeService);
}).Return(0);
var shouldBeOne = serviceFacadeStub.Execute(service => service.Method1("StringArgument1"));
var shouldBeTwo = serviceFacadeStub.Execute(service => service.Method1("StringArgument2"));
Assert.AreEqual(1, shouldBeOne);
Assert.AreEqual(2, shouldBeTwo);
}
我用fakeService
执行lambda,然后根据给定的参数返回结果。
另一种选择是像你一样使用Matches
,但是你必须使用反射来分析lambda ......(它要复杂得多......)
答案 1 :(得分:0)
只是因为其他人有同样的问题,我想出了什么。我开始使用NSubstitute而且很容易
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:windowSoftInputMode="adjustPan">