>source

나는 다음이있다 Controller 상호 작용:

public interface IInformationController
{
  string GetStoredInformation();
  string GetInformation();
}

컨트롤러 클래스는 다음과 같습니다.

public class InformationController : ControllerBase, IInformationController
{
  private InformationProvider1 InformationProvider1;
  private InformationProvider2 InformationProvider2;
  private IBasicRepository repository;
  public InformationController(IBasicRepository basicRepository)  
    => repository = basicRepository;
  public string GetStoredInformation()
    => repository.GetStoredInformation();
  public string GetInformation()
    => $"Information is {informationProvider1.GetInformationHeader()}, Information detail is {informationProvider2.GetInformationDetail()}";
  
}

나는 단위 테스트를 의도 InformationControllerxUnit 및 Moq.

이것은 내 테스트 클래스입니다.

public class InformationControllerTest
{
  public InformationControllerTest()
  {
    repositoryMock = new Mock<IBasicRepository>();
    repositoryMock.Setup(repository => repository.GetStoredInformation()).Returns("Stored information");
    SUT = new InformationController(repositoryMock.Object);
  }
  [Fact]
  public void GetStoredInformation_Returns_Stored_Information()
  {
    string result = SUT.GetStoredInformation();
    Assert.Equal("Stored information", result);
  }
  [Fact]
  public void GetInformation_Returns_Valid_Information()
  {
    string result = SUT.GetInformation(); //TODO: how to avoid the usage of actual provider implementations?
    Assert.Equal("Information is Header1, Information detail is Detail1", result);
  }
}

보시다시피 개인 공급자가 있습니다. 불행히도 tgey는 외부 종속성이며 종속성 주입을 통해 쉽게 도입 할 수 없습니다.

실제 통화를 어떻게 조롱해야합니까? 컨트롤러 메서드를 모의해야합니까 (실제 컨트롤러 테스트 프로세스를 무효화해야하는 imho)? 종속성 주입을 통해 가져와야합니까?

  • 답변 # 1

    단위 테스트는 현재 설계의 단점을 드러내며 외부 종속성 또는 구현 문제와 밀접하게 연결됩니다.

    종속성은 해당 종속성에 명시 적으로 주입되어야합니다.

    Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.

    명시 적 종속성 원칙 참조

    public class InformationController : ControllerBase, IInformationController {
        private IInformationProvider1 informationProvider1;
        private IInformationProvider2 informationProvider2;
        private IBasicRepository repository;
        public InformationController(IBasicRepository basicRepository,
            IInformationProvider1 informationProvider1, 
            IInformationProvider2 informationProvider2) {
            repository = basicRepository;
            this.informationProvider1 = informationProvider1;
            this.informationProvider2 = informationProvider2
        }
        public string GetStoredInformation()
            => repository.GetStoredInformation();
        public string GetInformation()
            => $"Information is {informationProvider1.GetInformationHeader()}, Information detail is {informationProvider2.GetInformationDetail()}";
      
        //...
    }
    
    

    이러한 외부 종속성에 대한 추상화 및 구현을 만든 다음 DI 컨테이너에 등록하여 런타임에 해결되고 컨트롤러에 적절하게 제공 될 수 있도록합니다. 이제 실제 구현에서 원하지 않는 부작용없이 격리 된 상태에서 테스트 할 수도 있습니다.

관련 자료

  • 이전 Google Play Store에서 Huawei Store로 마이그레이션 코드가 변경 되었습니까?
  • 다음 javascript - 약속을 사용한 후 정리하는 방법