2008-10-07 4 views
4

이 asp.net에서 교착 상태가 발생할 가능성을 제거하고 있습니다. 코드가 제대로 처리되도록하려면 교착 상태를 유발하는 NUnit 테스트를 작성하려고합니다 .....Nunit에서 데이터베이스 교착 상태 테스트를 만들 수 있습니까?

DAO는 엔티티별로 분할됩니다. 각 엔터티에는 Startup() 및 Teardown() 메서드로 둘러싸인 일련의 테스트가 있으며,이 메서드는 트랜잭션 범위를 만든 다음 테스트가 완료된 후에 롤백합니다. 이것은 다른 모든 것에 잘 작동하지만 교착 상태에서는 완전히 쓸모가 없습니다.

안정적으로 재현 할 수있는 TransactionScope 및 SQL2000 (예 : MSDTC가 포함됨)을 사용하여 "교착 상태"테스트를 설정하고 실행할 수 있습니까? 세부 정보 : 두 명의 사용자가 서로 다른 특정 데이터 값을 사용하여 두 개의 함수를 호출하면 교착 상태가 일 수 있으므로 결과가 나타나는 경우가 있습니다. 어떻게 NUNIT 내에서 이것을 시뮬레이션 할 수 있습니까? 그리고 교착 상태를 항상이 발생하게 만드시겠습니까?

그렇습니다. "처음에는 교착 상태가 발생하지 않도록하는 것이 좋습니다"라는 계획부터 시작했지만 교착 상태가 발생할 수있는 코드를 제어 할 수는 없습니다. 교착 상태가 될 수 있습니다.

답변

2

교착 상태로 인해 예외가 발생하는 경우 모의 객체를 사용하여 예외를 에뮬레이트합니다.

MockObject mo = MockManager.MockObject(typeof(MyDeadlockException)); 
mock.ExpectAndThrow("MyMethod", (MyDeadlockException)mo.Object); 

아이디어는 기본적으로 다른 조롱 프레임 워크에 대해 동일합니다 :

기본 개념

는 대신 예외를 던질 같은 것을 당신의 모의 객체 프레임 워크를 (내가 TypeMock처럼) 말할 것입니다.

+0

나는이 아이디어를 좋아한다. Mock 프레임 워크에 대한 아이디어가 있지만 사용하지는 않았습니다. 나는 "ExpectAndThrow"메쏘드가 실제로 예외가 던져지게 할 것이므로, 나의 코드가 그것을 잡을 수 있다고 가정하고있다. 나는 이것을 더 깊이 살펴볼 것이다. –

+0

그게 정확히 무엇입니까. 나는 그것을 사용하지 않았지만, 예산 문제가 있다면 Rhino.Mocks는 무료입니다 : http://ayende.com/projects/rhino-mocks.aspx –

0

거래가 진행되는 동안 테스트 중 하나가 5 분 동안 "대기"하면 어떻게됩니까? 또는 트랜잭션을 시작하고 새 레코드를 만든 다음 커밋하지 않고 해당 레코드를 업데이트하는 테스트를 작성하기 만하면됩니다. 그런 다음 새 트랜잭션을 시작하고 작성된 레코드를 읽으려고 시도하고 현재 업데이트 중입니다. 거기에 교착 상태가 발생합니다.

+0

동일한 스레드에서 두 개의 트랜잭션을 만들면 TransactionScope를 사용하여 교착 상태가 발생할 수 없습니다. 하나의 txn을 만든 다음 첫 번째 트랜잭션을 작성하지 않고 다른 트랜잭션을 작성하면 두 번째 트랜잭션은 첫 번째 트랜잭션 내에서 중첩됩니다. –

0

수동으로 테이블을 잠근 경우 항상 잠긴 상태로 두었습니까? 그런 다음 해당 테이블에 대해 취한 조치로 교착 상태가 발생합니까?

+0

"수동으로"MSDTC를 사용하여 트랜잭션을 작성하는 것은 간단하지 않습니다. 쿼리 분석기에서 트랜잭션을 시작할 수는 있지만 분산 트랜잭션은 아니며 쿼리 분석기에서 "롤백"할 때까지 데이터베이스 작업을 수행하지 못하도록 MSDTC 트랜잭션을 잠급니다. –

0

이 맹인은 나오지만 실제로 데이터베이스에 SQLConnection을 만들려면 TestSetup 메서드에서 수행 할 수 있습니까? 그런 다음이를 사용하여 테이블을 잠그는 명령을 내리거나 레코드 또는 페이지를 잠그기위한 조치를 취할 수 있습니까? 그렇게하면 다른 거래가 발생하지 않을 것입니다. 이것이 당신이 이미 생각한 선택 일 것 같습니다. 너의 상황에 대해 나는 무엇을 놓치고 있는가?

+0

데드락을 생성하기위한 선결 조건은 트랜잭션을 발행하는 두 개의 분리 된 프로세스가 될 것이라고 생각합니다. 하나의 프로세스 내에서 "인공"잠금을 만들면 교착 상태가 발생하지 않습니다. 리소스가 해제 될 때까지 기다려야합니다. NUNIT에서 이것을 시뮬레이션 할 수있는 방법이 필요했습니다. –

+0

수동으로 강제로 실행하지 않는 방법은 없습니다. 이제는 NUnit 내부에서 수동으로 강제로 수행 할 수 있지만 여전히 수동으로 강제로 수행 할 수 있습니다. 교착 상태 시나리오를 생성하는 환경을 만들어야합니다. –

0

단위 테스트의 경우 실제로 데이터베이스를 사용하지 않는 것이 좋습니다. 교착 상태가 있다는 것을 어떻게 알 수 있습니까? 교착 상태가 있음을 알리는 조건을 테스트하고 테스트에서이를 작성해야합니다.

모의는 서비스를 호출하면 오류를 반환하는 이상적인 메시지입니다. 가짜가 당신이 예상하고있는 오류를 반환하게하십시오. 타임 아웃이나 무언가를 기다리고 있다면 같은 일이 적용됩니다.

일반적으로 단위 테스트는 테스트중인 코드에서만 실행되어야하며 다른 코드 나 구성 요소에 의존해서는 안됩니다. 그건 - 데이터베이스는 본질적으로 또 다른 구성 요소이며 아마도 nunit을 사용하여 일종의 기능 테스트를 수행하고있을 것입니다.

그런 경우 교착 상태 상황을 만들어야하지만 레코드 또는 테이블을 잠그고 동일한 레코드를 사용하고 응답을 처리하는 구성 요소를 호출해야합니다.

+0

"이 경우에는 교착 상태 상황을 만들어야합니다. 레코드를 잠그거나 테이블을 잠그고 같은 레코드를 사용하고 응답을 처리하려고하는 구성 요소를 호출합니다. " 교착 상태가 아니라 차단을 설명합니다. –

+0

우리는 교착 상태가 발생할 수 있음을 알고 있습니다. 라이브 앱의 현재 버전의 erorrs 로그가 있기 때문입니다. UnitTests가 일반적으로 DB를 테스트해서는 안되지만 변경하지 않는 테스트를 위해 UnitTestDB를 설치했습니다. 상태. –

1

대부분의 솔루션에는 여러 스레드가 있습니다. 여기에는 그렇지 않습니다.

Close these Loopholes - Reproduce Database Errors

저자는 알렉스 쿠즈 네 초프입니다.

+0

deadlocker 클래스를 호출하는 테스트와 데드락 크래커 클래스를 사용하면 어떻게 기존의 asp.net 앱에 대한 특정 호출에서 교착 상태를 테스트 할 수 있을지 모르겠습니다. 그래도 흥미로운 기사. –