아무것도 반환하지 않는 메소드를 단위 테스트하는 가장 좋은 방법은 무엇입니까? 특히 C #에서.
실제로 테스트하려고하는 것은 로그 파일을 가져 와서 특정 문자열에 대해 구문 분석하는 방법입니다. 그런 다음 문자열이 데이터베이스에 삽입됩니다. 이전에 수행되지 않았지만 TDD에 매우 새로운 것은 아무것도 테스트 할 수 있는지 또는 실제로 테스트되지 않은 것이 아닌지 궁금합니다.
아무것도 반환하지 않는 메소드를 단위 테스트하는 가장 좋은 방법은 무엇입니까? 특히 C #에서.
실제로 테스트하려고하는 것은 로그 파일을 가져 와서 특정 문자열에 대해 구문 분석하는 방법입니다. 그런 다음 문자열이 데이터베이스에 삽입됩니다. 이전에 수행되지 않았지만 TDD에 매우 새로운 것은 아무것도 테스트 할 수 있는지 또는 실제로 테스트되지 않은 것이 아닌지 궁금합니다.
답변:
메소드가 아무것도 리턴하지 않으면 다음 중 하나입니다.
명령 방식-작업이 실제로 수행되었는지 확인할 수 있습니다. 상태 변경이 실제로 발생했는지 확인하십시오. 예 :
void DeductFromBalance( dAmount )
이 메시지를 게시 한 잔액이 dAmount의 초기 값보다 작은 지 확인하여 테스트 할 수 있습니다
정보 방법-객체의 공용 인터페이스의 구성원으로서 드물기 때문에 일반적으로 단위 테스트를 거치지 않습니다. 그러나 필요한 경우 알림 처리가 수행되는지 확인할 수 있습니다. 예 :
void OnAccountDebit( dAmount ) // emails account holder with info
이메일이 전송되고 있는지 확인하여 테스트 할 수 있습니다
실제 방법에 대한 자세한 내용을 게시하면 사람들이 더 잘 답변 할 수 있습니다.
업데이트 : 당신의 방법은 두 가지 일을하고 있습니다. 실제로 그것을 독립적으로 테스트 할 수있는 두 가지 방법으로 나눕니다.
string[] ExamineLogFileForX( string sFileName );
void InsertStringsIntoDatabase( string[] );
첫 번째 방법에 더미 파일과 예상 문자열을 제공하면 String []을 쉽게 확인할 수 있습니다. 두 번째는 약간 까다 롭습니다. Mock (구글 프레임 워크의 Google 또는 검색 스택 오버 플로우)을 사용하여 DB를 모방하거나 실제 DB를 치고 문자열이 올바른 위치에 삽입되었는지 확인할 수 있습니다. 확인 이 스레드를 좋은 책을 ... 당신이 위기에 있다면 나는 실용 단위 테스트를 recomment 것입니다.
코드에서 다음과 같이 사용됩니다
InsertStringsIntoDatabase( ExamineLogFileForX( "c:\OMG.log" ) );
부작용을 테스트하십시오. 여기에는 다음이 포함됩니다.
물론 테스트 할 수있는 양 에는 제한 이 있습니다. 예를 들어 일반적으로 가능한 모든 입력으로 테스트 할 수는 없습니다. 실용적으로 테스트-코드가 적절하게 설계되고 올바르게 구현되었음을 확신 할 수있을 정도로 충분하며 발신자가 기대할 수있는 보충 문서 역할을 할 수 있습니다.
무효 반환 유형 / 서브 루틴은 오래된 뉴스입니다. 나는 8 년 동안 Void 반환 유형을 만들지 않았습니다 (내가 매우 게으르지 않은 한) (이 답변 시점 부터이 질문을하기 전에 조금만).
다음과 같은 방법 대신 :
public void SendEmailToCustomer()
Microsoft의 int.TryParse () 패러다임을 따르는 메소드를 작성하십시오.
public bool TrySendEmailToCustomer()
아마도 장기적으로 사용하기 위해 메소드가 리턴해야하는 정보가 없을 수도 있지만 메소드를 수행 한 후 메소드 상태를 리턴하는 것은 호출자에게 큰 도움이됩니다.
또한 bool이 유일한 상태 유형은 아닙니다. 이전에 만든 서브 루틴이 실제로 3 개 이상의 다른 상태 (Good, Normal, Bad 등)를 반환 할 수있는 경우가 많습니다. 이런 경우에는
public StateEnum TrySendEmailToCustomer()
그러나 Try-Paradigm은 보이드 리턴을 테스트하는 방법에 대해이 질문에 어느 정도 대답하지만 다른 고려 사항도 있습니다. 예를 들어, "TDD"주기 동안 / 후에, 당신은 "리팩토링 (refactoring)"을하게되며 방법으로 두 가지 일을하고 있다는 것을 알 수 있습니다. "단일 책임 원리" 따라서 먼저 처리해야합니다. 둘째로, 당신은 의존성을 이념화했을 수도 있습니다. 당신은 "영구적 인"데이터를 만지고 있습니다.
의뢰 방법에서 데이터 액세스 작업을 수행하는 경우 n 계층 또는 n 계층 아키텍처로 리팩토링해야합니다. 그러나 "문자열이 데이터베이스에 삽입된다"고 말하면 실제로 비즈니스 로직 계층 또는 다른 것을 호출한다는 의미입니다. 나중에 가정하겠습니다.
객체가 인스턴스화되면 이제 객체에 종속성이 있음을 이해합니다. 이것은 객체 또는 메소드에서 종속성 주입을 수행할지 여부를 결정해야 할 때입니다. 즉, 생성자 또는 요청 방법에 새로운 매개 변수가 필요합니다.
public <Constructor/MethodName> (IBusinessDataEtc otherLayerOrTierObject, string[] stuffToInsert)
이제 비즈니스 / 데이터 계층 개체의 인터페이스를 수락 할 수 있으므로 단위 테스트 중에이를 모방 할 수 있으며 "사고"통합 테스트에 대한 종속성이나 두려움이 없습니다.
따라서 라이브 코드에서는 REAL IBusinessDataEtc
객체 를 전달 합니다. 그러나 단위 테스트에서는 MOCK IBusinessDataEtc
객체 를 전달 합니다. 모의 점에서, 당신은 비 인터페이스와 같은 속성이 포함될 수 있습니다 int XMethodWasCalledCount
그 상태 (들) 인터페이스 메소드가 호출 될 때 업데이트됩니다 또는 무언가를.
따라서 단위 테스트는 질문에 대한 방법 (들)을 거치고, 가지고있는 논리를 수행하고, IBusinessDataEtc
개체 에서 하나 또는 두 개 또는 선택된 메서드 집합을 호출 합니다. 단위 테스트가 끝날 때 어설 션을 수행하면 몇 가지 테스트 할 사항이 있습니다.
IBusinessDataEtc
객체 의 상태입니다 .시공 레벨에 대한 의존성 주입 아이디어에 대한 자세한 내용은 유닛 테스팅과 관련이 있습니다. 현재 가지고있는 각각의 현재 인터페이스 / 클래스에 대해 인터페이스와 클래스를 하나 더 추가하지만, 매우 작으며 더 나은 단위 테스트를 위해 엄청난 기능 향상을 제공합니다.
public void sendEmailToCustomer() throws UndeliveredMailException
합니까?
void
특히 객체 지향 언어 방법, 그것은 유일한 옵션이었다. 마이크로 소프트의 가장 오래된 대안은 제가 이야기하는 Try-Paradigm과 Monads / Maybes와 같은 Functional-style 패러다임입니다. 따라서 CQS에서 Commands는 던지기에 의존하는 대신 여전히 가치있는 상태 정보를 반환 할 수 있습니다 GOTO
. 던지기 (및 이동)는 느리고 디버깅하기가 어렵고 좋은 습관이 아닙니다.
이 시도:
[TestMethod]
public void TestSomething()
{
try
{
YourMethodCall();
Assert.IsTrue(true);
}
catch {
Assert.IsTrue(false);
}
}
ExpectedAttribute
더 명확하게이 시험을 수 있도록 설계되었습니다.
이 방법으로 시도해 볼 수도 있습니다.
[TestMethod]
public void ReadFiles()
{
try
{
Read();
return; // indicates success
}
catch (Exception ex)
{
Assert.Fail(ex.Message);
}
}
아마도 메소드가 무언가를 수행하고 단순히 반환하지 않습니까?
이 경우를 가정하면 다음과 같습니다.
방법이 무엇인지 알려 주면 더 구체적 일 수 있습니다.
Rhino Mocks 를 사용 하여 어떤 호출, 동작 및 예외가 예상 될지 설정 하십시오 . 분석법의 일부를 조롱하거나 스터 빙 할 수 있다고 가정합니다. 방법이나 상황에 대한 구체적인 내용을 알지 못하면 알기가 어렵습니다.
그것이하는 일에 달려 있습니다. 매개 변수가있는 경우 나중에 올바른 매개 변수 집합으로 호출되었는지 묻는 모의를 전달하십시오.
void 메소드를 호출하는 데 사용하는 인스턴스는 무엇이든 사용할 수 있습니다.Verfiy
예를 들어 :
내 경우 _Log
에는 인스턴스이며 LogMessage
테스트 할 방법입니다.
try
{
this._log.Verify(x => x.LogMessage(Logger.WillisLogLevel.Info, Logger.WillisLogger.Usage, "Created the Student with name as"), "Failure");
}
Catch
{
Assert.IsFalse(ex is Moq.MockException);
}
(가)인가 Verify
로 인해 테스트가 실패하는 방법의 실패로 예외를 throw?