2010-01-06 3 views
3

사용자가 이벤트 페이지에 전자 메일 주소를 입력 할 때 이벤트 미리 알림을 추가해야한다는 요구 사항이 있습니다. 이벤트가 다른 도메인 객체입니다. 우리의 초기 생각은 고객의 도메인 객체와 관련 CustomerService를을 만드는 것이었다 :유닛 테스팅 도메인 객체

public class CustomerService { 
    public void AddEventReminder(string emailAddress, int eventId) { 
     var customer = new Customer(emailAddress); 
     customer.AddEmailReminder(eventId); 
    } 
} 

어떻게 우리가 AddEmailReminder 방법은 실제로 새로운 고객에 호출되었음을 단위 테스트에서 확인할 수 있습니까?

내 생각 :

  1. 사용 고객을 만드는 공장. 왜냐하면 나는 당신이 단지 객체 생성에 약간의 복잡성이있는 공장을 사용하기로되어 있다고 생각했기 때문에 냄새가 난다.
  2. 잘못된 코드입니다. 아마 이것을 할 수있는 더 좋은 방법이 있을까요?
  3. Moq magic.

별도의 메모 (관련이있을 수 있음)에서 어떻게 집계 루트를 결정합니까? 우리는 고객이 임의로 결정했으나 똑같이 이벤트 일 수 있습니다. 나는 골재 뿌리에 대한 기사를 읽고 이해했으나이 시나리오에서는 명확하지 않다.

답변

6

이와 같은 경우 나는 고객을 생성하는 서비스에서 보호 된 메소드를 작성하고 테스트에서는 해당 메소드를 익명의 내부 클래스로 대체하여 mock Customer 오브젝트를 리턴하게한다. 그런 다음 AddAmailReminder가 호출 된 mock Customer 객체를 확인할 수 있습니다. 뭔가 같은 :

public class CustomerService { 
    public void AddEventReminder(string emailAddress, int eventId) { 
     var customer = createCustomer(emailAddress); 
     customer.AddEmailReminder(eventId); 
    } 

    protected Customer createCustomer(string emailAddress) { 
     return new Customer(emailAddress); 
    } 
} 

시험에서 (제한 C#을 지식을 가정하지만,이 점을 설명해야합니다) 다음 CustomerService를 API에 대한

void testCustomerCreation() { 
    /* final? */ Customer mockCustomer = new Customer("email"); 
    CustomerService customerService = new CustomerService() { 
     protected Customer createCustomer(string emailAddress) { 
      return mockCustomer; 
     }    
    }; 

    customerService.AddEventReminder("email", 14); 

    assertEquals(mockCustomer.EventReminder() /* ? */, 14); 
} 
2

생각을

이 어떤 있습니까 CustomerService에서이 작업을 캡슐화하기로 결정한 특별한 이유는 무엇입니까? 이것은 나에게 조금 Anemic를 보인다. 대신 고객에게 직접 캡슐화 될 수 있습니까?

public void AddEventReminder(Customer customer, int eventId) 

하지만 : 당신이해야하는 경우

아마도 당신은 고객 인스턴스를 적용하려면 문제 시그니처를 해결 변경,

그러나 ...

물건을 단순화 CustomerService를 코드 예제의 무언가를 남겨 다시 Int32는 도메인 객체로는 거의 적합하지 않으므로 서명은 실제로는

public void AddEventReminder(Customer customer, Event event) 

이됩니다. 어떤 가치?

어떤 것이 총계입니까?

그들 중 누구도 생각하지 못했습니다. 집계 루트는 루트를 통해 자식 만 관리한다는 것을 나타내며,이 경우 어느 쪽이든 이해가되지 않습니다.루트 이벤트를 한 경우

, 그것은 더 CustomerRepository이 없었다 것을 의미하고, 유일한 방법은 검색, 편집 및 고객이 이벤트를 통해 것 지속될 수 :

이 옵션을 고려하십시오. 그건 나에게 매우 잘못된 것처럼 들린다.

고객을 루트로 만들면 EventRepository를 사용할 수 없으며 이벤트를 검색, 편집 및 유지할 수있는 유일한 방법은 특정 고객을 통한 것입니다. 그건 나에게 잘못된 것처럼 들린다.

유일한 나머지 가능성은 별도의 뿌리입니다. 이것은 또한 서로 느슨하게 연결되어 있으며 고객 이벤트 또는 고객 이벤트를 조회하기 위해 일종의 도메인 서비스가 필요하다는 것을 의미합니다.

+0

이 도메인 서비스 방법의 요점은 전자 메일 주소와 이벤트 ID가있는 dto를받은 응용 프로그램 서비스에서 직접 호출된다는 것입니다. 나는 도메인 객체가 완전한 객체만을 다루어야한다고 생각 했으므로 도메인 서비스는 이것을 처리해야한다. 도메인 객체가 모든 논리에 관한 것처럼 다른 방법으로 생각할 수 있다면, 빈약하다는 것이 왜 도메인 서비스로 진행해서는 안된다는 의미인지 나는 알지 못합니다. 다시 합계 루트, 그들은 모두 집계 뿌리에 동의, 내가 묻고 있던 질문은 집계 루트가 협회에 대한 책임은 무엇입니까? – JontyMC

+0

... 재미있는 대답. 서명을 변경하려면 Customer aggregate root를 작성하는 코드는 무엇입니까? 아마도 이것은 더 적절한 질문입니다. – JontyMC

+0

서비스가 응용 프로그램 계층에서 매핑되는 것으로 의심됩니다. 그러나이 경우 도메인 서비스는 아니며 응용 프로그램 계층 서비스이며 해당 계층에 속합니다. 이 경우 전자 메일 주소를 기반으로 기존 고객을 조회 할 수있는 추상 팩토리 (아마도 CustomerRepository)가 필요하다고 생각합니다. –