공개 생성자없이 어떻게 모의/가짜/스터브 밀봉 된 OracleException을 할 수 있습니까?
-
02-07-2019 - |
문제
내 테스트에서 나는 OracleException이 발생했을 때 (저장된 절차 고장으로 인해) 발생하는 일을 테스트해야합니다. Rhino Mocks를 설정하려고합니다
Expect.Call(....).Throw(new OracleException());
그러나 어떤 이유로 든 OracleException은 공개 생성자없이 봉인 된 것 같습니다. 이것을 테스트하려면 어떻게해야합니까?
편집하다: 내가 인스턴스화하려는 내용은 다음과 같습니다.
public sealed class OracleException : DbException {
private OracleException(string message, int code) { ...}
}
해결책
Oracle은 생성자를 이후 버전으로 변경 한 것으로 보이므로 위의 솔루션은 작동하지 않습니다.
오류 코드 만 설정하려면 다음이 2.111.7.20에 대한 트릭을 수행합니다.
ConstructorInfo ci = typeof(OracleException)
.GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new Type[] { typeof(int) },
null
);
Exception ex = (OracleException)ci.Invoke(new object[] { 3113 });
다른 팁
Oracle의 관리 데이터 액세스 (v 4.121.1.0)의 경우 생성자가 다시 변경되었습니다.
var ci = typeof(OracleException).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(int), typeof(string), typeof(string), typeof(string) }, null);
var c = (OracleException)ci.Invoke(new object[] { 1234, "", "", "" });
다음은 다음과 같습니다.
ConstructorInfo ci = typeof(OracleException).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] {typeof(string), typeof(int)}, null);
var c = (OracleException)ci.Invoke(new object[] { "some message", 123 });
도움이 된 모든 덕분에 당신은 반전되었습니다.
oracle.dataaccess.client data provider 클라이언트를 사용하고 있습니다. OracleException 객체의 새로운 인스턴스를 구성하는 데 어려움이 있지만 공개 생성자가 없다고 계속 말합니다. 위에 표시된 모든 아이디어를 시도하고 Null 참조 예외를 계속 얻었습니다.
object[] args = { 1, "Test Message" };
ConstructorInfo ci = typeof(OracleException).GetConstructor(BindingFlags.NonPublic
| BindingFlags.Instance, null, System.Type.GetTypeArray(args), null);
var e = (OracleException)ci.Invoke(args);
테스트 코드를 디버깅 할 때는 항상 'CI'에 대한 널 값을 얻습니다.
Oracle은이를 허용하지 않도록 도서관을 변경 했습니까? 내가 무엇을 잘못하고 있고 NMock과 함께 사용할 OracleException 객체를 인스턴스화하기 위해 무엇을해야합니까?
그건 그렇고, 저는 버전 10G 용 클라이언트 라이브러리를 사용하고 있습니다.
감사,
백인
반사를 사용하여 OracleException을 인스턴스화하십시오. 보다 이 블로그 게시물
반사를 사용하여 OracleException 객체를 인스턴스화 하시겠습니까? 바꾸다
new OracleException()
~와 함께
object[] args = ... ;
(OracleException)Activator.CreateInstance(typeof(OracleException), args)
항상 이와 같은 모든 생성자를 얻을 수 있습니다
ConstructorInfo[] all = typeof(OracleException).GetConstructors(
BindingFlags.NonPublic | BindingFlags.Instance);`
을 위한 Oracle.DataAccess
4.112.3.0 이것은 7 개의 생성자를 반환했습니다
내가 원했던 것은 5 개의 논쟁을 취한 목록에서 두 번째였습니다. int, string, string, string, int
. 나는 다섯 번째 논쟁에 놀랐다.
internal OracleException(int errCode, string dataSrc, string procedure, string errMsg)
{
this.m_errors = new OracleErrorCollection();
this.m_errors.Add(new OracleError(errCode, dataSrc, procedure, errMsg));
}
그래서, 내가 원했던 생성자를 얻기 위해 결국 사용했습니다.
ConstructorInfo constructorInfo =
typeof(OracleException).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new Type[] { typeof(int), typeof(string), typeof(string), typeof(string), typeof(int) },
null);`
좋은 해결책 George. 이것은 Sqlexection에도 효과적입니다.
ConstructorInfo ci = typeof( SqlErrorCollection ).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null );
SqlErrorCollection errorCollection = (SqlErrorCollection) ci.Invoke(new object[]{});
ci = typeof( SqlException ).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof( string ), typeof( SqlErrorCollection ) }, null );
return (SqlException) ci.Invoke( new object[] { "some message", errorCollection } );
-Dave
매번 실패/오류가 발생하는 사소한 저장된 절차를 작성한 다음 테스트하는 데 사용할 수 있습니까?