2011-04-13 84 views
3
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); 
    } 

}Rhinomocks - 懲戒代表

我捻熄服務和返回集合。當我運行這個測試時,媒體是空的。任何想法,我如何設定這個模擬的期望?

回答

2

剛剛找到了解決方案。它似乎有點難看,但它是第一次迭代,可能會更快更優雅的版本。我們的想法是創建另一個存根和匹配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 +擴展名被用作測試框架。請忽略TheoryInlineData的東西 - 這是擺脫不必要的測試設置的另一種方法。

下面是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); 
} 

希望這會有所幫助。如何添加更多美麗的任何建議,歡迎:)