저는 sitecore 개발자이며 "EmailArticleController"컨트롤러에서 볼 수있는 로직을 테스트하기위한 샘플 Sitecore 헬릭스 유닛 테스트 프로젝트를 만들고 싶습니다. 색인() 액션 메소드 : 그것은 (문자열) 데이터 소스를 가지고Sitecore.Mvc.Presentation.RenderingContext를 사용하는 GlassController 작업 단위 테스트 방법
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Test_EmailArticleController_With_RenderingContext()
{
//Arrange
var businessLogicFake = new Mock<IEmailArticleBusiness>();
var model = new EmailArticleViewModel()
{
ArticleControl = new Article_Control() { },
Metadata = new Metadata() { }
};
businessLogicFake.Setup(x => x.FetchPopulatedModel).Returns(model);
// I'm not sure about the next 3 lines, how do I mock the RenderingContext and send it into the constructor, given that it needs a DataSource value too?
var renderingContext = Mock.Of<Sitecore.Mvc.Presentation.RenderingContext>(/*what goes here, if anything?*/) { /*what goes here, if anything?*/ };
EmailArticleController controllerUnderTest = new EmailArticleController(businessLogicFake.Object, renderingContext);
var result = controllerUnderTest.Index(3) as ViewResult;
Assert.IsNotNull(result);
}
}
은 기본적으로 내가, 렌더링 컨텍스트를 조롱 있는지 확인하려면이
using Sitecore.Mvc.Presentation;
public class EmailArticleController : GlassController
{
//logic in below Index() method is what I want to test
public override ActionResult Index()
{
var _emailArticleBusiness = new EmailArticleBusiness();
var model = _emailArticleBusiness.FetchPopulatedModel;
var datasourceId = RenderingContext.Current.Rendering.DataSource;
_emailArticleBusiness.SetDataSourceID(datasourceId);
return View("~/Views/EmailCampaign/EmailArticle.cshtml", model);
}
//below is alternative code I wrote for mocking and unit testing the logic in above Index() function
private readonly IEmailArticleBusiness _businessLogic;
private readonly RenderingContext _renderingContext;
public EmailArticleController(IEmailArticleBusiness businessLogic, RenderingContext renderingContext)
{
_businessLogic = businessLogic;
_renderingContext = renderingContext;
}
public ActionResult Index(int forUnitTesting)
{
var model = _businessLogic.FetchPopulatedModel;
// *** do below two lines of logic somehow go into my Unit Testing class? How?
var datasourceId = _renderingContext.Rendering.DataSource;
_businessLogic.SetDataSourceID(datasourceId);
// ***
return View("~/Views/EmailCampaign/EmailArticle.cshtml", model);
}
}
확인을 내 단위 테스트 클래스에있는 것입니다 값을 "/ sitecore/home/..."과 같이 설정하면 I w 개미가 컨트롤러의 생성자 (적절한 방법이라면)로 보내고, Index (int) 메서드를 호출하고, 동시에이 경우 인터페이스 인 _businessLogic을 확인하십시오 (구체적인 클래스 여야합니다. ?)보기를 반환하기 전에 동일한 값으로 설정된 dataSource가 있습니다.
이 모든 작업을 수행하기위한 정확한 코드는 무엇입니까? 감사!
답변 해 주셔서 감사합니다. 그것은 매력처럼 일했습니다! "RenderingContext.Current.Rendering.DataSource와 같은 정적 종속성에 코드를 밀접하게 연결하면 코드를 독립적으로 테스트 할 수 없으므로 RenderingContext에 대한 정적 액세스를 캡슐화하는 래퍼를 만드는 것이 가장 좋습니다." 단위 테스트를 위해 EmailArticleController() 클래스에 절대적으로 코드를 추가해야하는 다른 이유가 있습니까? 생성자에 아무것도 보내지 않고 원래의 Index() 메서드를 단위 테스트 할 수있는 방법이 없다는 것을 의미합니까? – user3034243
@ user3034243 더 많은 디자인이 필요합니다. 정적 종속성에 대한 제어권이 없으므로 정상 작동을 벗어난 경우 필요할 때 초기화 방법을 제어 할 수 없습니다. 자신이 소유하지 않은 코드를 제어 할 수 없기 때문에 별도로 테스트하기가 어렵습니다. SOLID와 같은 주제를 읽으면 유지 관리가 쉬운 깨끗한 코드를 디자인하는 것과 관련하여 테스트를 포함하는 방법을 더 잘 이해할 수 있습니다. – Nkosi
@ user3034243 나는 가능한 다른 방법이있을 것이라고 거의 확신하지만, 쉽게 시작할 수있는 디자인을 쉽게 할 수있을 때마다 사냥을한다. 나는 매번보다 깨끗한 디자인을 선택한다. – Nkosi