2015-01-08 5 views
1
I 클래스의 저장소에 생성자 주입을 사용한

, 나는 다음과 같은 작품을 발견했습니다 실패의 원인이 고객 객체를 추가 : 의존성 삽입 (Dependency Injection) - 테스트

public CreateInvoiceResult CreateInvoice(string Code, int qty, string Name) 
    { 

     if (string.IsNullOrEmpty(Code) || qty <= 0 || repository.GetByName(Name).ID <= 0) 
     { 
      return new CreateInvoiceResult(false); 
     } 

그러나 다음 코드로 변경

가 (에 추가 '를 고객의 Cust ') 테스트가 실패하게됩니까?

public CreateInvoiceResult CreateInvoice(string stockCode, int quantity, string customerName) 
{ 
    Customer cust = repository.GetByName(Name); 

    if (string.IsNullOrEmpty(Code) || qty <= 0 || cust.ID <= 0) 
    { 
     return new CreateInvoiceResult(false); 
    } 

예 테스트 : 왜 이런 일

는 설명 할 수 제발 내가 어떻게 해결할 수 있습니다?

편집 :

[TestClass] 
public class MockCustomerRepositoryDBTests 
{ 
    public MockCustomerRepositoryDBTests() 
    { 
     IList<Customer> customers = new List<Customer> 
     { 
      new Customer { ID = 1, Name = "Jim Smith", 
       Address = "14 Main Road"}, 
      new Customer { ID = 2, Name = "Alex Smith", 
       Address = "78 Avanue"}, 
      new Customer { ID = 3, Name = "Paul Brown", 
       Address = "1 Main Road"} 
     }; 

     // Mock the CustomerRepositoryDB Repository using Moq 
     Mock<ICustomerRepository> mockCustomerRepository = new Mock<ICustomerRepository>(); 

     // Return a customer by Name 
     mockCustomerRepository.Setup(mr => mr.GetByName(
      It.IsAny<string>())).Returns((string s) => customers.Where(
      x => x.Name == s).Single()); 

     // Complete the setup of the Mock Customer Repository 
     this.MockCustomerRepository = mockCustomerRepository.Object; 
    } 

    public readonly ICustomerRepository MockCustomerRepository; 

    [TestMethod] 
    public void stockCodeIsNullOrEmpty() 
    { 
     //Arrange 
     var x = new InvoiceController(MockCustomerRepository); 

     //Act 
     bool result = x.CreateInvoice("", 1, "test").Success; 

     //Assert 
     Assert.AreEqual(result, false); 
    } 

은 방법 : 올바른 저장소 사용, MOQ를 사용하여 테스트를 업데이트 한 'System.InvalidOperationException이 : 시퀀스가 ​​포함를 어떤 요소'

+0

moq에 대한 별도의 질문을해야합니다. –

+0

원래 질문을 모두 삭제할 필요가 없습니다. :) 내가 다시 돌려 놓을 게다. –

답변

1

전화

Customer _Customer = repository.GetByName(customerName); 

입니다 아마도 약간의 예외 만 있으면 실패 할 것입니다. 당신이 당신의 클래스를 보면

당신은이 생성자에서 당신에게 저장소 개체를 초기화 :

//Arrange 
var x = new PartInvoiceController(); 

그래서 저장소 : 당신은 당신이 시험에 전화 기본 생성자를 제공하지만

public PartInvoiceController(ICustomerRepository custRepo) 
{ 
    this.repository = custRepo; 
} 

절대 초기화되지 않으므로 null 참조 예외가 발생합니다.

왜 전에 실패하지 않았습니까?

string.IsNullOrEmpty(stockCode)이 true이고 다른 조건이 conditional-or operator (||)을 사용하여 조합 되었기 때문에 if 문에 포함 된 경우 실행되지 않았으므로 중요하지 않습니다. 따라서 조건을 단락시킬 수 있습니다 조건은 모든 조건이 평가되지 않더라도 true 또는 false가 될 것입니다.

이 때문에 if 문이 입력되었고 다른 조건은 평가되지 않았으므로 저장소가 null 인 것은 결코 실행되지 않은 코드입니다.

수정하려면 테스트 (스텁 또는 모의)에 사용할 저장소를 제공하거나 기본 생성자에서 기본 저장소를 만들거나 원래 코드로 되돌려 야합니다 (' 이 테스트에서 초기화되지 않은 저장소에 대한 관심).

은 다음과 같이 테스트를 변경

: 당신이 당신의 모의 문제에 대한 또 다른 질문을하지해야하지만, 기본적으로는 이름이 "시험"을 가진 사용자를 찾고 있지만 아무도 정말

[TestMethod] 
public void stockCodeIsNullOrEmpty() 
{ 
    ICustomerRepository testRepository = //create a test repository here 
    //Arrange 
    var x = new PartInvoiceController(testRespository); 

    //Act 
    bool result = x.CreatePartInvoice("", 1, "test").Success; 

    //Assert 
    Assert.AreEqual(result, false); 
} 

편집 모의 저장소의 사용자 이름이

+0

당신의 도움에 감사드립니다 - 나는 "System.NullReferenceException : 개체 참조가 개체의 인스턴스로 설정되지 않았습니다."라고 생각합니다. - 내가 어떻게 수정 하겠어? –

+0

답변 끝에 답변을 수정하는 방법에 대한 정보를 제공했습니다. 테스트에 저장소를 제공해야합니다. 그렇지 않으면 클래스를 사용하여 사용자를 얻는 데 사용할 저장소가 있습니까? –

+0

아 좋아, 네 도움을 주셔서 감사합니다. :) –

1
Customer _Customer = repository.GetByName(customerName); 

회원 변수 "repository"가 초기화되지 않았습니다. PartInvoiceController 클래스의 다른 생성자를 사용해야합니다.

관련 문제