2012-12-23 2 views
1

저는 Moq에 생성자에 기본 매개 변수가있는 추상 클래스를 사용하고 싶습니다. 이것은 testnig 특정 값뿐만 아니라 기본값이 설정되었는지 테스트 할 수 있도록하기 위해서입니다. 예 : 다음과 같이 MOQ 객체를기본 생성자 매개 변수로 Moq 추상 클래스를 만드는 방법은 무엇입니까?

public abstract class AbstractClassToTest 
    { 
     private string _name; 
     private int _someInt; 
     private int _anotherInt; 

     public AbstractClassToTest(string name, int someInt = 10, int anotherInt = 20) 
     { 
      _name = name; 
      _someInt = someInt; 
      _anotherInt = anotherInt; 
     } 
    } 

(이 순전히 예를 들어 클래스입니다주의) 및 설정 :

var act = new Mock<AbstractClassToTest>(MockBehavior.Loose, "namestring"); 

을하지만,이 오류가 발생합니다 ...

Message "Can not instantiate proxy of class: 
Test.AbstractClassToTest. 
Could not find a constructor that would match given arguments: 
System.String 
Parameter name: constructorArguments" 

을 어떻게 할 수 moq 객체를 만들고 기본값을 유지 하시겠습니까?

MOQ : V 4.0.10827.0

답변

2

MOQ 뜻이되지 모의 수업 유형 만 인터페이스. 아마도 추상 클래스조차도 그것에 "구체적인"구현을 많이 가질 수 있고 많은 상태를 가질 수 있기 때문일 것입니다.

대신, 자신의 조롱 클래스를 만들 :

class AbstractClassToTestMOCK : AbstractClassToTest 
{ 
    internal AbstractClassToTestMOCK(string name, int someInt = 10, int anotherInt = 20) 
    : base(name, someInt, anotherInt) 
    { 
    } 
} 

편집 :

내 원래의 대답의 첫 번째 단락은 모두 틀렸다. 나는 (정적이 아닌) 클래스 유형을 모방하는 것이 가능하다는 것을 확인했다. (인스턴스는이어야하고, 내부적으로 중첩 된 모든 클래스/구조체는 인터페이스와 마찬가지로 public이어야한다.) 인스턴스 생성자 문제의 질문은 public 또는 protected (또는 protected internal)입니다. public 또는 protectedSetup 모두 virtual (abstract 포함) 메서드 (및 속성, 인덱서 등)를 사용할 수 있습니다.

원래의 질문으로 돌아가려면 이름이 붙은 선택적 인수가 리플렉션에 의해 잘 지원되지 않는 문법적 설탕의 일종이라는 문제가 있습니다. 그에서

protected AbstractClassToTest(string name) 
    : this(name, someInt: 10, anotherInt: 20) 
{ 
} 

: 원래 AbstractClassToTest 수정할 수있는 경우

이 문제를 해결하기 위해 또 다른 전략은, 당신의 원래 클래스에이 추가되고, 인스턴스 생성자를 오버로드하는 것입니다 원래 생성자의 매개 변수를 선택적으로 유지하려는 경우와 그렇지 않은 경우가 있습니다.

PS! abstract 클래스의 인스턴스 생성자는 public이 아니어야합니다. 대신 protected을 사용하십시오.

+1

Moq은 추상적 인 클래스를 모의 처리 할 수 ​​있습니다 (그리고 비 추상적 클래스라고 생각합니다). 추상 또는 가상의 프록시를 만듭니다. 재정의를 설정하거나 기본 멤버를 호출 할 수 있습니다. 그러나 생성자에서 기본 매개 변수를 처리하는 더 좋은 방법이 있다는 것을 모릅니다. 그러나 @BlueChippy가 기본값을 그대로두기를 원한다면 예제 에서처럼 재정의하지 않을 것입니다. 대신,'MockClass (string name) : base (name/* 기본값을 실제로 디폴트 * /)'로 두십시오. 이야기의 요지 : "Moq은 클래스 유형을 모의하지 않으며 인터페이스 만"이 사실이 아닙니다. – DBueno

+0

@DBueno 그것을 지적 해 주셔서 감사합니다! 편집 됨. –

관련 문제