2016-06-04 22 views
3

Ich versuche das herauszufinden, aber keinen Erfolg. Wie kann ich ProcessorLocator für diese beiden Tests nachbilden?Moq Service Locator für Komponententest

Hier ist mein Servicelocator:

public class ProcessorLocator : IProcessorLocator 
{ 
    public static IContainer Container; 

    T IProcessorLocator.GetProcessor<T>() 
    { 
     return Container.Resolve<T>(); 
    } 

    public static IServiceProvider Init(IServiceCollection services) 
    { 
     //Autofac 
     var containerBuilder = new ContainerBuilder(); 
     containerBuilder.RegisterModule<ProcessorRegistrationModule>(); 
     containerBuilder.RegisterType<ProcessorLocator>().As<IProcessorLocator>(); 
     containerBuilder.Populate(services); 
     Container = containerBuilder.Build(); 

     return Container.Resolve<IServiceProvider>(); 
    } 

    public class ProcessorRegistrationModule : Autofac.Module 
    { 
     protected override void Load(ContainerBuilder builder) 
     { 
      Assembly asm = typeof(ProcessorLocator).GetTypeInfo().Assembly; 

      builder.RegisterAssemblyTypes(asm) 
       .Where(t => t.Name.EndsWith("Processor")) 
       .As(t => t.GetInterfaces().FirstOrDefault(
        i => i.Name == "I" + t.Name)); 

      builder.RegisterAssemblyTypes(asm) 
       .Where(t => t.Name.EndsWith("Repository")) 
       .As(t => t.GetInterfaces().FirstOrDefault(
        i => i.Name == "I" + t.Name)); 
     } 
    } 
} 

Hier ist meine Klasse im Test:

public class MainNavigationViewComponent : ViewComponent 
{ 
    public IProcessorLocator _ProcessorLocator { get; set; } 

    public MainNavigationViewComponent(IProcessorLocator processorLocator) 
    { 
     _ProcessorLocator = processorLocator; 
    }  

    public IViewComponentResult Invoke() 
    { 
     IMenuItemRepository _menuItemRepository = _ProcessorLocator.GetProcessor<IMenuItemRepository>(); 

     IEnumerable<Entity.MenuItem> _menuItemList = _menuItemRepository.GetAll().Where(x => x.Parent == null && x.onMenu == true); 

     return View(_menuItemList.ToList()); 
    } 
} 

Meine Versuche:

[Fact] 
public void ActualTest() 
{ 
    //var mockS = new Mock<IProcessorLocator>(); 
    //ProcessorLocator.Container.SetLocatorProvider(() => mockS.Object); 
    var container = BL.ProcessorLocator.InitTest(); 
    _menuItemMock.Setup(x => x.GetAll()).Returns(new List<MenuItem>() { new MenuItem() { Text = "uu"}, new MenuItem() { Text = "zz" } }); 

    IMenuItemRepository _menuItemRepository = container.Resolve<IMenuItemRepository>(); 

    IEnumerable<Entity.MenuItem> _menuItemList = _menuItemRepository.GetAll().Where(x => x.Parent == null && x.onMenu == true); 
} 

[Fact] 
public void MainNavigationViewComponent Test() 
{ 
     //var _subject = new MainNavigationViewComponent(_menuItemMock.Object) 
     //{ 
     // ActionContext = new ActionContext() 
     // { 
     //  HttpContext = new DefaultHttpContext() 
     // } 
     //}; 
} 
+1

erklärt Wenn es schwierig ist, einen Komponententest zu schreiben, ist etwas falsch bei der Implementierung. Ich kann sagen, dass Ihr ProcessorLocator mehr als eine Verantwortung hat. Wenn Sie daran arbeiten, werden Sie andere Probleme sehen und Ihre Probleme lösen. –

Antwort

4

basierend auf dem Code Sie zur Verfügung gestellt haben:

var fakeMenuRepository = new Mock<IMenuItemRepository>(); 
fakeMenuRepository.Setup(repository => repository.GetAll()) 
        .Returns(new List<MenuItem>() 
        { 
         new MenuItem() { Text = "uu" }, 
         new MenuItem() { Text = "zz" } 
        }); 
var fakeLocator = new Mock<IProcessorLocator>(); 
fakeLocator.Setup(locator => locator.GetProcessor<IMenuItemRepository>()) 
      .Returns(fakeMenuRepository.Object); 

var target = new MainNavigationViewComponent(fakeLocator.Object); 

Eine weitere Option besteht darin, einen echten Container zu verwenden und dann die Instanz IMenuItemRepository zu überschreiben; wie ich in this answer

+0

das funktioniert wie ein Traum. Danke – Mert