2010-10-01 9 views
6

मैंने SO पर एक खोज की और ऐसा लगता है कि इस सवाल को अक्सर पूछताछ की जाती है। मैं mocks काम करने में सक्षम हो गया है और मैं बिना किसी मुद्दे के OnActionExecuted() निष्पादित करने में सक्षम हूं। मेरा यूनिट टेस्ट यहाँ है। टिप्पणी की गई पंक्तियां असफल होती हैं और मुझे यकीन है कि मैं सही प्रकार का मज़ाक उड़ा रहा हूं।यूनिट परीक्षण कार्य फ़िल्टर - ViewResult नकली कैसे करें

 //Arrange 
     //var viewResult = new ViewResult(); 
     var filterContextMock = new Mock<ActionExecutedContext>(); 
     var routeData = new RouteData(); 
     var httpContextMock = new Mock<HttpContextBase>(); 

     routeData.Values["data"] = "Mock data"; 
     var requestContext = new RequestContext(httpContextMock.Object, routeData); 

     var controller = new FakeController(); 
     controller.ControllerContext = new ControllerContext(requestContext, controller); 

     filterContextMock.Setup(f => f.RouteData).Returns(routeData); 
     filterContextMock.Setup(f => f.Controller).Returns(controller); 
     //filterContextMock.Setup(f => f.Result).Returns(viewResult); 

     //Act 
     var wrapFilterAttribute = new WrapFilterAttribute(); 
     wrapFilterAttribute.OnActionExecuted(filterContextMock.Object); 

यहां मेरा एक्शन फ़िल्टर है।

public class WrapFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     var view = (ViewResultBase)filterContext.Result; 

     if (view != null) 
     { 
      BaseViewModel viewModel = (BaseViewModel)view.ViewData.Model ?? new BaseViewModel(); 
      viewModel.Wrap = new WrapperFactory().GetWrap(); 
     } 

     base.OnActionExecuted(filterContext); 
    } 
} 

मुद्दा मैं यहाँ का सामना करना पड़ रहा हूँ filterContext.Result हमेशा EmptyResult के रूप में आता है। मैं इसके बजाय एक हाइड्रेटेड ViewResult में धक्का देना चाहता हूँ। कोई विचार है कि मैं इसे कैसे पूरा कर सकता हूं?

बहुत धन्यवाद!

उत्तर

9

पहले की वर्तमान कोड बुरा लग रहा है के रूप में अपनी कार्रवाई फिल्टर फिक्सिंग से शुरू करते हैं और उन लोगों के कास्टिंग आप सिर दर्द लाने सकता है:

public class WrapFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     var view = filterContext.Result as ViewResultBase; 
     if (view != null) 
     { 
      // the controller action returned a ViewResultBase 
      var viewModel = view.ViewData.Model as BaseViewModel; 
      if (viewModel != null) 
      { 
       // the model passed to the view was derived from 
       // BaseViewModel so we can safely update the Wrap 
       // property 
       viewModel.Wrap = new WrapperFactory().GetWrap(); 
      } 
     } 
     base.OnActionExecuted(filterContext); 
    } 
} 

और इकाई परीक्षण:

// arrange 
var sut = new WrapFilterAttribute(); 
var filterContextMock = new Mock<ActionExecutedContext>(); 
var viewResultMock = new Mock<ViewResultBase>(); 
filterContextMock.Object.Result = viewResultMock.Object; 
var viewModel = new BaseViewModel(); 
viewResultMock.Object.ViewData.Model = viewModel; 

// act 
sut.OnActionExecuted(filterContextMock.Object); 

// assert 
// TODO: assert something on the viewModel.Wrap property like 
// for example that it has been initialized 

टिप्पणी: आपका कार्रवाई फिल्टर WrapperFactory कक्षा पर एक मजबूत निर्भरता है। यह अच्छा नहीं है। एक और सुधार एक इंटरफेस में इस कार्यक्षमता को अमूर्त करने के लिए होगा जो कार्रवाई फ़िल्टर के निर्माता में इंजेक्शन दिया जाएगा। यह आपको आपके आवेदन की विभिन्न परतों के बीच चिंताओं को और अलग करने की अनुमति देगा।

+0

मेरे क्रैपी कोड डारिन को दोबारा करने के लिए धन्यवाद। यह मेरे लिए काम किया। धन्यवाद फिर से :) – Praveen

+0

कार्रवाई फ़िल्टर कन्स्ट्रक्टर में WrapperFactory इंजेक्शन के बारे में आपकी टिप्पणी मुझे उत्सुक बनाता है। WrapFilterAttribute सजावट के माध्यम से WrapperFactory के उदाहरण में आप कैसे भेजना चाहते हैं? AFAIK, विशेषताओं को संकलन-समय मान (स्थिरांक इत्यादि) की आवश्यकता होती है। – Praveen

+1

@Praveen, यहां एक उदाहरण है कि कैसे प्राप्त करें [एक्शन फ़िल्टर के साथ कन्स्ट्रक्टर इंजेक्शन] (http://iridescence.no/post/Constructor-Injection-for-ASPNET-MVC-Action-Filters.aspx)। यह थोड़ा हैकी है लेकिन इस पल के लिए यही एकमात्र तरीका है। यह एएसपी.नेट एमवीसी 3. –

संबंधित मुद्दे