"void"를 반환하는이 메서드에 대한 단위 테스트를 작성 중입니다. 예외가 발생하지 않았을 때 테스트가 통과하는 경우를 하나 갖고 싶습니다. C #으로 어떻게 작성합니까?
Assert.IsTrue(????)
(내 생각 엔 이것이 내가 확인해야하는 방법이지만 "???"에 들어가는 내용)
내 질문이 충분히 명확하기를 바랍니다.
"void"를 반환하는이 메서드에 대한 단위 테스트를 작성 중입니다. 예외가 발생하지 않았을 때 테스트가 통과하는 경우를 하나 갖고 싶습니다. C #으로 어떻게 작성합니까?
Assert.IsTrue(????)
(내 생각 엔 이것이 내가 확인해야하는 방법이지만 "???"에 들어가는 내용)
내 질문이 충분히 명확하기를 바랍니다.
답변:
예외가 발생하면 단위 테스트는 실패합니다. 특별한 어설 션을 입력 할 필요가 없습니다.
이것은 어설 션이 전혀없는 단위 테스트를 볼 수있는 몇 안되는 시나리오 중 하나입니다. 예외가 발생하면 테스트가 암시 적으로 실패합니다.
그러나 만약 당신이 정말로 이것에 대한 주장을 작성하고 싶었다면-아마도 예외를 잡아 내고 "예외를 예상했지만 이것을 얻었습니다 ..."를보고 할 수 있다면, 다음과 같이 할 수 있습니다 :
[Test]
public void TestNoExceptionIsThrownByMethodUnderTest()
{
var myObject = new MyObject();
try
{
myObject.MethodUnderTest();
}
catch (Exception ex)
{
Assert.Fail("Expected no exception, but got: " + ex.Message);
}
}
(위는 NUnit의 예이지만 MSTest의 경우도 마찬가지입니다.)
NUnit에서는 다음을 사용할 수 있습니다.
Assert.DoesNotThrow(<expression>);
코드에서 예외가 발생하지 않는다고 주장합니다. Assert가 없어도 예외가 발생하면 테스트가 실패하지만,이 접근 방식의 가치는 테스트에서 충족되지 않은 기대치와 버그를 구별 할 수 있고 다음과 같은 사용자 지정 메시지를 추가 할 수 있다는 것입니다. 테스트 출력에 표시됩니다. 잘 구성된 테스트 출력은 코드에서 테스트 실패를 유발 한 오류를 찾는 데 도움이 될 수 있습니다.
코드가 예외를 던지지 않도록 테스트를 추가하는 것이 타당하다고 생각합니다. 예를 들어 입력의 유효성을 검사하고 들어오는 문자열을 long으로 변환해야한다고 가정합니다. 문자열이 null 인 경우가있을 수 있으며 이는 허용 가능하므로 문자열 변환에서 예외가 발생하지 않도록해야합니다. 따라서이 경우를 처리 할 코드가 있으며 테스트를 작성하지 않은 경우 중요한 논리 부분에 대한 커버리지가 누락됩니다.
public class TestBase { //believe me, I don't like this anymore than you do. protected void AssertDoesNotThrow(Action action, string message) { try { action(); } catch (Exception) { Assert.Fail(message); } } }
어떤 일이 일어나지 않는다는 것을 테스트하지 마십시오 . 코드 가 깨지지 않도록 하는 것과 같습니다 . 그것은 일종의 암시 적이며, 우리 모두는 깨지지 않는 버그없는 코드를 위해 노력합니다. 그것에 대한 테스트를 작성하고 싶습니까? 왜 한 가지 방법일까요? 모든 메서드가 예외를 throw하지 않도록 테스트하고 싶지 않습니까? 그 길을 따라 가면 코드베이스의 모든 메서드에 대해 하나의 추가 더미, 어설 션없는 테스트 로 끝납니다 . 가치가 없습니다.
물론, 메서드 가 예외를 포착 하는지 확인하는 것이 요구 사항이라면 이를 테스트 (또는 약간 반전하고 포착해야하는 것을 던지지 않는지 테스트)합니다.
그러나 일반적인 접근 방식 / 관행은 그대로 유지됩니다. 테스트 된 코드의 범위를 벗어난 일부 인위적 / 모호한 요구 사항에 대한 테스트를 작성하지 않습니다. 특히 방법의 책임이 잘 알려진 시나리오에서).
간단하게 말하면 코드 가 수행 해야하는 작업에 집중 하고이를 테스트합니다.
이 도우미 클래스는 MSTest로 내 가려움증을 긁었습니다. 아마도 그것은 당신의 것을 긁을 수 있습니다.
[TestMethod]
public void ScheduleItsIneligibilityJob_HasValid_CronSchedule()
{
// Arrange
var factory = new StdSchedulerFactory();
IScheduler scheduler = factory.GetScheduler();
// Assert
AssertEx.NoExceptionThrown<FormatException>(() =>
// Act
_service.ScheduleJob(scheduler)
);
}
public sealed class AssertEx
{
public static void NoExceptionThrown<T>(Action a) where T:Exception
{
try
{
a();
}
catch (T)
{
Assert.Fail("Expected no {0} to be thrown", typeof(T).Name);
}
}
}
Assert
있는 단일 속성 접근 That
자를 가지고 있습니다. 그것은 깔끔한 수 있습니다, 그리고 더 많은 검색 가능하도록 Assert.That.DoesNotThrow()
보다는 AssertEx.DoesNotThrow()
. 이것은 단지 의견입니다.
Assert.Whatever
일관성을 위해 각 테스트가 끝날 때마다 보기를 좋아합니다 .
나에게 이것은 간단하게 Assert.IsTrue(true);
나는 실수로 그 코드를 거기에 넣지 않았다는 것을 알고 있으므로 이것이 의도 한대로 훑어 보면서 충분히 확신 할 수 있어야합니다.
[TestMethod]
public void ProjectRejectsGappedVersioningByDefault() {
var files = new List<ScriptFile>();
files.Add(ScriptProjectTestMocks.GetVersion1to2());
files.Add(ScriptProjectTestMocks.GetVersion3to4());
Assert.Throws<ScriptProject.InvalidProjectFormatException>(() => {
var sut = new ScriptProject(files);
});
}
[TestMethod]
public void ProjectAcceptsGappedVersionsExplicitly() {
var files = new List<ScriptFile>();
files.Add(ScriptProjectTestMocks.GetVersion1to2());
files.Add(ScriptProjectTestMocks.GetVersion3to4());
var sut = new ScriptProject(files, true);
Assert.IsTrue(true); // Assert.Pass() would be nicer... build it in if you like
}
내 친구 Tim이 ExpectedException 에 대해 나에게 말했다 . 나는이 b / c가 더 간결하고 코드가 적으며 예외를 테스트하고 있다는 것이 매우 분명합니다.
[TestMethod()]
[ExpectedException(typeof(System.Exception))]
public void DivideTest()
{
int numerator = 4;
int denominator = 0;
int actual = numerator / denominator;
}
여기에서 더 많은 것을 읽을 수 있습니다 : ExpectedException Attribute Usage .