2011-09-24 4 views
0

내 프로젝트에는 ServiceModule로 일반적인 방법으로 초기화되는 IoC 컨테이너가 있습니다. 단위 테스트를 작성할 때 StrictMock, DynamicMock, PartialMock 또는 Stub 중 하나에 바인딩 할 수 있어야합니다. 과거에는 StrictMocks에 모든 것을 묶는 FakeServiceModule이 있었지만 이것은 매우 제한적이었고, 필자가 선택한 모의 유형을 만들 수 있도록 확장하려고했습니다.Ninject and dynamic WithConstructor/WithMeta and RhinoMocks

이렇게하려면 다음을 생성했습니다. ...

 foreach (var mockType in _mocks) 
     { 
      object ninjaMock; 

      switch (mockType.MockTypeToUse) 
      { 
       case MockType.Strict: 
        { 
         ninjaMock = _mockRepository.StrictMock(mockType.TypeToMock); 
         break; 
        } 
       case MockType.Dynamic: 
        { 
         ninjaMock = _mockRepository.DynamicMock(mockType.TypeToMock); 
         break; 
        } 
       case MockType.Partial: 
        { 
         ninjaMock = _mockRepository.PartialMock(mockType.TypeToMock); 
         break; 
        } 
       case MockType.Stub: 
        { 
         ninjaMock = _mockRepository.Stub(mockType.TypeToMock); 
         break; 
        } 
       default: 
        { 
         ninjaMock = _mockRepository.StrictMock(mockType.TypeToMock); 
         break; 
        } 
      } 

      if (mockType.BindingWithOrOnSyntax == typeof(ConstructorArgument)) 
       Bind(mockType.TypeToMock).ToMethod(m => ninjaMock).w 
        .WithConstructorArgument(mockType.BindingWithOrOnSyntax); 

      else 
       Bind(mockType.TypeToMock).ToMethod(m => ninjaMock); 
     } 

는 모의 객체의 목록을 initliazed 된 데이 모두가 완벽하게 작동

 NinjectMocking ninjectMocking = new NinjectMocking(); 
     ninjectMocking.TypeToMock = typeToAdd; 
     ninjectMocking.MockTypeToUse = MockType.Dynamic; 

:

public class NinjectMocking 
{ 
    public Type TypeToMock { get; set; } 
    public MockType MockTypeToUse { get; set; } 
    public IBindingWithOrOnSyntax<Type> BindingWithOrOnSyntax { get; set; } 
} 

public enum MockType 
{ 
    Stub, 
    Strict, 
    Dynamic, 
    Partial 
} 

아이디어는 내가 그렇게 같은 가짜 서비스 모듈을 초기화 것입니다 . 그러나 여기에서 문제는 우리의 바인딩의 일부는 미래에

 Bind<ISomeRepository>().ToMethod(m => someRepository) 
     .WithConstructorArgument("context", ctx => new TestDataContext()); 

같이 어쩌면 일부 다른 .WithConstructorArgument 또는 .WithMetaData 중 하나가 필요 온다. 그래서 NinjectMocking 클래스에 BindingWithOrOnSyntax 속성이 있습니다. 그래서 내 새로운 초기화 프로그램은 다음과 같이 보일 수 있습니다.

 NinjectMocking ninjectMocking = new NinjectMocking(); 
     ninjectMocking.TypeToMock = typeToAdd; 
     ninjectMocking.MockTypeToUse = MockType.Dynamic; 
     ninjectMocking.BindingWithOrOnSyntax.WithConstructorArgument("context", constructorArgument); 

문제는 바인딩에서 사용하는 방법을 모르겠다는 것입니다. 내가 뭘하고 싶은

바인딩 (mockType.TypeToMock) .ToMethod 같은 것입니다 (m => ninjaMock). WhatGoesHere]

정말 [WhatGoesHere]와 함께 할 방법을 모른다 비트, 또는 BindingWithOrOnSyntax 속성에서 전달하는 모든 것을 사용하도록 Bind를 정의하는 방법을 설명합니다. 마지막 절망적 인 시도는 다음과 같은 것을 통해 강제로 시도하는 것입니다.

  if (mockType.BindingWithOrOnSyntax == typeof(ConstructorArgument)) 
       Bind(mockType.TypeToMock).ToMethod(m => ninjaMock) 
        .WithConstructorArgument(mockType.BindingWithOrOnSyntax); 

하지만 분명히 작동하지 않습니다.

올바른 방향의 포인터 또는이를 달성하는 더 좋은 방법이 있다면 크게 감사하겠습니다.

답변

2

단위 테스트 중에 IOC 용기를 사용하지 마십시오. IOC 컨테이너는 런타임시 구성 요소에 종속성을 주입하는 데 사용됩니다. 단위 테스트를 수행하는 동안 은 조롱 된/스터브 종속성을 사용하여 구성 요소를 만듭니다. 구성 요소가 IOC 컨테이너에서 직접 종속성을 해결할 경우 컨테이너를 올바르게 사용하지 않는 것입니다.