मॉकिंग और यूनिट टेस्टिंग के लिए जरूरत पड़ने पर SqlException को कैसे फेंकें?


85

मैं अपनी परियोजना में कुछ अपवादों का परीक्षण करने की कोशिश कर रहा हूं और एक अपवाद मैं पकड़ रहा हूं SQlException

ऐसा लगता है कि आप नहीं जा सकते new SqlException()इसलिए मुझे यकीन नहीं है कि मैं विशेष रूप से डेटाबेस को कॉल किए बिना किसी अपवाद को कैसे फेंक सकता हूं (और क्योंकि ये यूनिट परीक्षण हैं आमतौर पर सलाह दी जाती है कि डेटाबेस को धीमा होने के बाद से कॉल न करें)।

मैं NUnit और Moq का उपयोग कर रहा हूं, लेकिन मुझे यकीन नहीं है कि यह कैसे नकली है।

कुछ उत्तरों के जवाब में जो सभी ADO.NET पर आधारित लगते हैं, ध्यान दें कि मैं Linq से Sql का उपयोग कर रहा हूं। ताकि सामान पर्दे के पीछे की तरह हो।

@Matt Hamilton द्वारा अनुरोधित अधिक जानकारी:

System.ArgumentException : Type to mock must be an interface or an abstract or non-sealed class.       
  at Moq.Mock`1.CheckParameters()
  at Moq.Mock`1..ctor(MockBehavior behavior, Object[] args)
  at Moq.Mock`1..ctor(MockBehavior behavior)
  at Moq.Mock`1..ctor()

पहली पंक्ति में पोस्ट जब यह मज़ाक करने की कोशिश करता है

 var ex = new Mock<System.Data.SqlClient.SqlException>();
 ex.SetupGet(e => e.Message).Returns("Exception message");

आप सही हे। मैंने अपना उत्तर अपडेट कर दिया है, लेकिन यह अब बहुत उपयोगी नहीं है। DbException शायद पकड़ने के लिए बेहतर अपवाद है, लेकिन इस पर विचार करें।
मैट हैमिल्टन

वास्तव में काम करने वाले उत्तर विभिन्न प्रकार के अपवाद संदेशों का उत्पादन करते हैं। आपको किस प्रकार की ज़रूरत है, यह परिभाषित करना सहायक हो सकता है। उदाहरण के लिए "मुझे एक SqlException की आवश्यकता है जिसमें अपवाद संख्या 18487 है, जो निर्दिष्ट पासवर्ड की समाप्ति की ओर इशारा करता है।" ऐसा लगता है कि इस तरह के एक समाधान इकाई परीक्षण के लिए अधिक उपयुक्त है।
माइक क्रिश्चियन

जवाबों:


9

चूँकि आप Linq का उपयोग Sql के लिए कर रहे हैं, यहाँ NUnit और Moq का उपयोग करके आपके द्वारा बताए गए परिदृश्य के परीक्षण का एक नमूना है। मुझे आपके DataContext और उसमें आपके पास क्या उपलब्ध है, इसकी सही जानकारी नहीं है। अपनी आवश्यकताओं के लिए संपादित करें।

आपको कस्टम वर्ग के साथ डेटा कॉन्टेक्स्ट को लपेटने की आवश्यकता होगी, आप मोको के साथ डेटा कॉन्टेक्स्ट को मॉक नहीं कर सकते। आप SqlException को नकली नहीं कर सकते, क्योंकि यह सील है। आपको इसे अपने स्वयं के अपवाद वर्ग के साथ लपेटने की आवश्यकता होगी। इन दोनों चीजों को पूरा करना मुश्किल नहीं है।

चलिए शुरू करते हैं अपना टेस्ट:

[Test]
public void FindBy_When_something_goes_wrong_Should_handle_the_CustomSqlException()
{
    var mockDataContextWrapper = new Mock<IDataContextWrapper>();
    mockDataContextWrapper.Setup(x => x.Table<User>()).Throws<CustomSqlException>();

    IUserResository userRespoistory = new UserRepository(mockDataContextWrapper.Object);
    // Now, because we have mocked everything and we are using dependency injection.
    // When FindBy is called, instead of getting a user, we will get a CustomSqlException
    // Now, inside of FindBy, wrap the call to the DataContextWrapper inside a try catch
    // and handle the exception, then test that you handled it, like mocking a logger, then passing it into the repository and verifying that logMessage was called
    User user = userRepository.FindBy(1);
}

आइए परीक्षण को लागू करते हैं, पहले चलो हमारे Linq को रिपॉजिटरी पैटर्न का उपयोग करके Sql कॉल में लपेटते हैं:

public interface IUserRepository
{
    User FindBy(int id);
}

public class UserRepository : IUserRepository
{
    public IDataContextWrapper DataContextWrapper { get; protected set; }

    public UserRepository(IDataContextWrapper dataContextWrapper)
    {
        DataContextWrapper = dataContextWrapper;
    }

    public User FindBy(int id)
    {
        return DataContextWrapper.Table<User>().SingleOrDefault(u => u.UserID == id);
    }
}

इसके बाद IDataContextWrapper बनाएं, आप इस ब्लॉग पोस्ट को इस विषय पर देख सकते हैं, मेरा एक छोटा सा अंतर है:

public interface IDataContextWrapper : IDisposable
{
    Table<T> Table<T>() where T : class;
}

अगला CustomSqlException क्लास बनाएं:

public class CustomSqlException : Exception
{
 public CustomSqlException()
 {
 }

 public CustomSqlException(string message, SqlException innerException) : base(message, innerException)
 {
 }
}

यहाँ IDataContextWrapper का एक नमूना कार्यान्वयन है:

public class DataContextWrapper<T> : IDataContextWrapper where T : DataContext, new()
{
 private readonly T _db;

 public DataContextWrapper()
 {
        var t = typeof(T);
     _db = (T)Activator.CreateInstance(t);
 }

 public DataContextWrapper(string connectionString)
 {
     var t = typeof(T);
     _db = (T)Activator.CreateInstance(t, connectionString);
 }

 public Table<TableName> Table<TableName>() where TableName : class
 {
        try
        {
            return (Table<TableName>) _db.GetTable(typeof (TableName));
        }
        catch (SqlException exception)
        {
            // Wrap the SqlException with our custom one
            throw new CustomSqlException("Ooops...", exception);
        }
 }

 // IDispoable Members
}

91

आप इसे प्रतिबिंब के साथ कर सकते हैं, आपको इसे बनाए रखना होगा जब Microsoft परिवर्तन करता है, लेकिन यह काम करता है मैंने इसे अभी परीक्षण किया है:

public class SqlExceptionCreator
{
    private static T Construct<T>(params object[] p)
    {
        var ctors = typeof(T).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
        return (T)ctors.First(ctor => ctor.GetParameters().Length == p.Length).Invoke(p);
    }

    internal static SqlException NewSqlException(int number = 1)
    {
        SqlErrorCollection collection = Construct<SqlErrorCollection>();
        SqlError error = Construct<SqlError>(number, (byte)2, (byte)3, "server name", "error message", "proc", 100);

        typeof(SqlErrorCollection)
            .GetMethod("Add", BindingFlags.NonPublic | BindingFlags.Instance)
            .Invoke(collection, new object[] { error });


        return typeof(SqlException)
            .GetMethod("CreateException", BindingFlags.NonPublic | BindingFlags.Static,
                null,
                CallingConventions.ExplicitThis,
                new[] { typeof(SqlErrorCollection), typeof(string) },
                new ParameterModifier[] { })
            .Invoke(null, new object[] { collection, "7.0.0" }) as SqlException;
    }
}      

यह आपको SqlException की संख्या को नियंत्रित करने की भी अनुमति देता है, जो महत्वपूर्ण हो सकती है।


2
यह दृष्टिकोण काम करता है, आपको बस अधिक विशिष्ट होने की आवश्यकता है कि CreateException विधि क्या आप चाहते हैं क्योंकि दो अधिभार हैं। GetMethod कॉल को इसमें बदलें: .GetMethod ("CreateException", BindingFlags.ononPublic। BindingFlags.Static, null, CallingConventions.ExplicitThis, new [] {typeof (SqlErrorCollection), typeof (string), "नया" यह काम करता है
एरिक नॉर्डेनोक

मेरे लिये कार्य करता है। प्रतिभाशाली।
निक पाटारिस

4
टिप्पणियों से सुधार के साथ, एक मुट्ठी में बदल गया। gist.github.com/timabell/672719c63364c497377f - इस गहरी अंधेरी जगह से मुझे बाहर निकालने के लिए सभी को बहुत-बहुत धन्यवाद।
टिम एबेल

2
बेन जे एंडरसन का संस्करण आपको त्रुटि कोड के अलावा संदेश निर्दिष्ट करने की अनुमति देता है। gist.github.com/benjanderson/07e13d9a2068b32c2911
टोनी

9
डॉटनेट-कोर 2.0 के साथ काम करने के लिए इसे NewSqlExceptionपढ़ने की विधि में दूसरी लाइन बदलें :SqlError error = Construct<SqlError>(number, (byte)2, (byte)3, "server name", "error message", "proc", 100, null);
चक स्पेंसर

75

मेरे पास इसका हल है। मुझे यकीन नहीं है कि यह प्रतिभा या पागलपन है।

निम्न कोड एक नया SqlException बनाएगा:

public SqlException MakeSqlException() {
    SqlException exception = null;
    try {
        SqlConnection conn = new SqlConnection(@"Data Source=.;Database=GUARANTEED_TO_FAIL;Connection Timeout=1");
        conn.Open();
    } catch(SqlException ex) {
        exception = ex;
    }
    return(exception);
}

जिसके बाद आप ऐसा उपयोग कर सकते हैं (यह उदाहरण Moq का उपयोग कर रहा है)

mockSqlDataStore
    .Setup(x => x.ChangePassword(userId, It.IsAny<string>()))
    .Throws(MakeSqlException());

ताकि आप अपनी SqlException एरर हैंडलिंग को अपने रिपॉजिटरी, हैंडलर और कंट्रोलर में टेस्ट कर सकें।

अब मुझे जाकर लेटने की जरूरत है।


10
शानदार समाधान! मैंने कनेक्शन के इंतजार में कुछ समय बचाने के लिए इसमें एक संशोधन किया:new SqlConnection(@"Data Source=.;Database=GUARANTEED_TO_FAIL;Connection Timeout=1")
जोआना डर्क्स

2
मुझे आपके उत्तर के लिए आपके द्वारा जोड़ी गई भावना से प्यार है। इस समाधान के लिए धन्यवाद। यह एक दिमाग नहीं है और मुझे नहीं पता कि मैंने शुरू में इस बारे में क्यों नहीं सोचा। फिर से धन्यवाद।
pqsk

1
महान समाधान, बस यह सुनिश्चित करें कि आपके पास अपने स्थानीय मशीन पर GUARANTEED_TO_FAIL नामक डेटाबेस नहीं है;)
अमित जी

KISS का एक बढ़िया उदाहरण
Lup

यह सरल रूप से पागल समाधान है
Mykhailo Seniutovych

21

स्थिति के आधार पर, मैं आमतौर पर एक ConstructorInfo को प्राप्त करने के लिए GetUninitializedObject पसंद करता हूं । आपको बस इस बात से अवगत होना है कि यह कंस्ट्रक्टर को MSDN से कॉल नहीं करता है: उस वस्तु के द्वारा। " लेकिन मैं कहूंगा कि यह एक निश्चित कंस्ट्रक्टर के अस्तित्व पर भरोसा करने से कम भंगुर है।

[TestMethod]
[ExpectedException(typeof(System.Data.SqlClient.SqlException))]
public void MyTestMethod()
{
    throw Instantiate<System.Data.SqlClient.SqlException>();
}

public static T Instantiate<T>() where T : class
{
    return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(T)) as T;
}

4
इसने मेरे लिए काम किया, और आपके पास एक बार वस्तु के अपवाद का संदेश सेट करने के लिए:typeof(SqlException).GetField("_message", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(exception, "my custom sql message");
फिल कूपर

7
मैंने ErrorMessage और ErrorCode को प्रतिबिंबित करने के लिए इसे बढ़ाया। gist.github.com/benjanderson/07e13d9a2068b32c2911
बेन एंडरसन

13

संपादन संपादित करें : मुझे नहीं पता था कि SqlException सील है। मैं DbException का मजाक उड़ा रहा हूं, जो कि एक अमूर्त वर्ग है।

आप एक नया SqlException नहीं बना सकते हैं, लेकिन आप DbException को मॉक कर सकते हैं, जो SqlException से निकलता है। इसे इस्तेमाल करे:

var ex = new Mock<DbException>();
ex.ExpectGet(e => e.Message, "Exception message");

var conn = new Mock<SqlConnection>();
conn.Expect(c => c.Open()).Throws(ex.Object);

जब कनेक्शन को खोलने की कोशिश करता है तो आपका अपवाद फेंक दिया जाता है।

यदि आप Messageनकली अपवाद पर संपत्ति के अलावा कुछ भी पढ़ने की उम्मीद करते हैं, तो उन संपत्तियों पर "प्राप्त" के आधार पर Expect (या सेटअप, Moq के आधार पर) को मत भूलना।


आपको "संख्या" के लिए अपेक्षाएं जोड़नी चाहिए, जो आपको यह पता लगाने की अनुमति देती है कि किस प्रकार का अपवाद है (गतिरोध, समय समाप्त आदि)
सैम केसर

हम्म कैसे के बारे में जब अपने sql sql का उपयोग कर? मैं वास्तव में एक खुला (मेरे लिए किया है) नहीं करते हैं।
चोबो 2

यदि आप Moq का उपयोग कर रहे हैं तो संभवतः आप किसी प्रकार के डेटाबेस ऑपरेशन का मजाक उड़ा रहे हैं। ऐसा होने पर फेंकने के लिए सेट करें।
मैट हैमिल्टन

तो वास्तविक ऑपरेशन पर (वास्तविक विधि जो db पर कॉल करेगी)?
चोबो 2

क्या आप अपने डीबी व्यवहार का मजाक उड़ा रहे हैं? जैसे, अपने DataContext क्लास या कुछ का मज़ाक उड़ाना? यदि डेटाबेस ऑपरेशन में कोई त्रुटि हुई, तो जो भी ऑपरेशन इस अपवाद को फेंक देगा।
मैट हैमिल्टन

4

यकीन नहीं होता कि यह मदद करता है, लेकिन लगता है कि इस व्यक्ति (बहुत चालाक) के लिए काम किया है।

try
{
    SqlCommand cmd =
        new SqlCommand("raiserror('Manual SQL exception', 16, 1)",DBConn);
    cmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
    string msg = ex.Message; // msg = "Manual SQL exception"
}

यहां पाया गया: http://smartypeeps.blogspot.com/2006/06/how-to-throw-sqlexception-c-c.html


मैंने यह कोशिश की, लेकिन SqlException थ्रो पाने के लिए आपको अभी भी एक खुली SqlConnection ऑब्जेक्ट की आवश्यकता है।
MusiGenesis

मैं sql को linq का उपयोग करता हूं इसलिए मैं यह ado.net सामान नहीं करता। यह सब पर्दे के पीछे है।
चोबो 2

2

यह काम करना चाहिए:

SqlConnection bogusConn = 
    new SqlConnection("Data Source=myServerAddress;Initial
    Catalog=myDataBase;User Id=myUsername;Password=myPassword;");
bogusConn.Open();

इससे पहले कि यह अपवाद फेंकता है थोड़ा सा लगता है, इसलिए मुझे लगता है कि यह और भी तेजी से काम करेगा:

SqlCommand bogusCommand = new SqlCommand();
bogusCommand.ExecuteScalar();

कोड आपके लिए Hacks-R-Us द्वारा लाया गया।

अद्यतन : नहींं, दूसरा दृष्टिकोण एक ArgumentException फेंकता है, न कि SqlException।

अद्यतन 2 : यह बहुत तेजी से काम करता है (SqlException को एक सेकंड से भी कम समय में फेंक दिया जाता है):

SqlConnection bogusConn = new SqlConnection("Data Source=localhost;Initial
    Catalog=myDataBase;User Id=myUsername;Password=myPassword;Connection
    Timeout=1");
bogusConn.Open();

इससे पहले कि मैं इस एसयू पेज पर आता, दूसरे रास्ते की तलाश में मेरा अपना कार्यान्वयन था क्योंकि टाइमआउट अस्वीकार्य था। आपका अपडेट 2 अच्छा है लेकिन यह अभी भी एक सेकंड का है। इकाई परीक्षण सेट के लिए अच्छा नहीं है क्योंकि यह पैमाने पर नहीं है।
जॉन डेविस

2

मैंने देखा कि आपका प्रश्न एक साल पुराना है, लेकिन रिकॉर्ड के लिए मैं एक समाधान जोड़ना चाहूंगा जिसे मैंने हाल ही में Microsoft Moles का उपयोग करके खोजा था (आप यहां संदर्भ प्राप्त कर सकते हैं Microsoft Moles )

एक बार जब आपने System.Data नाम स्थान पर मोल ले लिया, तो आप इस तरह से SqlConnection.Open () पर SQL अपवाद का मज़ाक उड़ा सकते हैं:

//Create a delegate for the SqlConnection.Open method of all instances
        //that raises an error
        System.Data.SqlClient.Moles.MSqlConnection.AllInstances.Open =
            (a) =>
            {
                SqlException myException = new System.Data.SqlClient.Moles.MSqlException();
                throw myException;
            };

मुझे उम्मीद है कि यह भविष्य में इस सवाल को हिट करने वाले किसी व्यक्ति की मदद कर सकता है।


1
उत्तर देर से होने के बावजूद यह शायद सबसे साफ समाधान है, खासकर यदि आप पहले से ही अन्य उद्देश्यों के लिए मोल्स का उपयोग कर रहे हैं।
अमंडलिशस

1
ठीक है, आपको कार्य करने के लिए मोल्स फ्रेमवर्क का उपयोग करना चाहिए। पूरी तरह से आदर्श नहीं है, जब पहले से ही MOQ का उपयोग कर रहा है। यह समाधान .NET फ्रेमवर्क को कॉल को अलग कर रहा है। @ Default.kramer द्वारा उत्तर अधिक उपयुक्त है। मोल्स को विजुअल स्टूडियो 2012 अल्टिमेट में "फेक" के रूप में जारी किया गया था, और बाद में वीएस 2012 में अपडेट 2 के माध्यम से प्रीमियम। मैं फेक फ्रेमवर्क का उपयोग करने के लिए हूं, लेकिन आने वाले लोगों के लिए एक समय में एक मॉकिंग फ्रेमवर्क से चिपके रहना चाहिए। आपके बाद। ;)
माइक क्रिश्चियन

2

उनके समाधान फूला हुआ महसूस करते हैं।

Ctor आंतरिक है, हाँ।

(प्रतिबिंब का उपयोग किए बिना, सिर्फ सही मायने में यह अपवाद बनाने का सबसे आसान तरीका ...।

   instance.Setup(x => x.MyMethod())
            .Callback(() => new SqlConnection("Server=pleasethrow;Database=anexception;Connection Timeout=1").Open());

पेरैप्स वहाँ एक और विधि है जिसे फेंकने के लिए 1 सेकंड के समय की आवश्यकता नहीं है।


हा ... इतना आसान मुझे नहीं पता कि मैंने ऐसा क्यों नहीं सोचा ... परेशानी के बिना एकदम सही और मैं यह कहीं भी कर सकता हूं।
hal9000

संदेश और त्रुटि कोड सेट करने के बारे में क्या? ऐसा लगता है कि आपका समाधान इसकी अनुमति नहीं देता है।
सासुके उचिहा

@Sasuke Uchiha यकीन है, यह नहीं है। अन्य उपाय करते हैं। लेकिन अगर आपको केवल इस प्रकार के अपवाद को फेंकने की आवश्यकता है, तो प्रतिबिंब से बचने के लिए और बहुत कोड नहीं लिखना चाहते हैं तो आप इस समाधान का उपयोग कर सकते हैं।
बिली जेक ओ'कॉनर

1

(यह 6 महीने देरी से शुरू होता है, आशा है कि यह नेक्रोपोस्टिंग नहीं माना जाएगा कि मैं यहां एक मॉक से SqlCeException कैसे फेंकना चाहता हूं)।

यदि आपको केवल उस कोड का परीक्षण करने की आवश्यकता है जो एक अति साधारण वर्कअराउंड अपवाद को संभालता है:

public void MyDataMethod(){
    try
    {
        myDataContext.SubmitChanges();
    }
    catch(Exception ex)
    {
        if(ex is SqlCeException || ex is TestThrowableSqlCeException)
        {
            // handle ex
        }
        else
        {
            throw;
        }
    }
}



public class TestThrowableSqlCeException{
   public TestThrowableSqlCeException(string message){}
   // mimic whatever properties you needed from the SqlException:
}

var repo = new Rhino.Mocks.MockReposity();
mockDataContext = repo.StrictMock<IDecoupleDataContext>();
Expect.Call(mockDataContext.SubmitChanges).Throw(new TestThrowableSqlCeException());

1

अन्य सभी उत्तरों के आधार पर मैंने निम्नलिखित समाधान बनाया:

    [Test]
    public void Methodundertest_ExceptionFromDatabase_Logs()
    {
        _mock
            .Setup(x => x.MockedMethod(It.IsAny<int>(), It.IsAny<string>()))
            .Callback(ThrowSqlException);

        _service.Process(_batchSize, string.Empty, string.Empty);

        _loggermock.Verify(x => x.Error(It.IsAny<string>(), It.IsAny<SqlException>()));
    }

    private static void ThrowSqlException() 
    {
        var bogusConn =
            new SqlConnection(
                "Data Source=localhost;Initial Catalog = myDataBase;User Id = myUsername;Password = myPassword;Connection Timeout = 1");
        bogusConn.Open();
    }

1

यह वास्तव में पुराना है और यहां कुछ अच्छे उत्तर हैं। मैं Moq का उपयोग कर रहा हूं, और मैं एब्सट्रैक्ट क्लासेस का मजाक नहीं उड़ा सकता और वास्तव में प्रतिबिंब का उपयोग नहीं करना चाहता था, इसलिए मैंने DbException से प्राप्त अपना स्वयं का अपवाद बनाया। इसलिए:

public class MockDbException : DbException {
  public MockDbException(string message) : base (message) {}
}   

जाहिर है, अगर आपको इनर एक्सेप्शन, या जो कुछ भी जोड़ने की जरूरत है, अधिक प्रॉपर, कंस्ट्रक्टर आदि जोड़ें।

फिर, मेरे परीक्षण में:

MyMockDatabase.Setup(q => q.Method()).Throws(new MockDbException(myMessage));

Hoepfully यह किसी को भी मदद करेगा जो Moq का उपयोग कर रहा है। यहां पोस्ट किए गए सभी लोगों के लिए धन्यवाद जिसने मुझे अपने जवाब के लिए प्रेरित किया।


जब आपको SqlException पर कुछ विशिष्ट की आवश्यकता नहीं होती है, तो यह विधि वास्तव में अच्छी तरह से काम करती है।
राल्फ विलगॉस

1

मैं इस विधि का उपयोग करने का सुझाव देता हूं।

    /// <summary>
    /// Method to simulate a throw SqlException
    /// </summary>
    /// <param name="number">Exception number</param>
    /// <param name="message">Exception message</param>
    /// <returns></returns>
    public static SqlException CreateSqlException(int number, string message)
    {
        var collectionConstructor = typeof(SqlErrorCollection)
            .GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, //visibility
                null, //binder
                new Type[0],
                null);
        var addMethod = typeof(SqlErrorCollection).GetMethod("Add", BindingFlags.NonPublic | BindingFlags.Instance);
        var errorCollection = (SqlErrorCollection)collectionConstructor.Invoke(null);
        var errorConstructor = typeof(SqlError).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null,
            new[]
            {
                typeof (int), typeof (byte), typeof (byte), typeof (string), typeof(string), typeof (string),
                typeof (int), typeof (uint)
            }, null);
        var error =
            errorConstructor.Invoke(new object[] { number, (byte)0, (byte)0, "server", "errMsg", "proccedure", 100, (uint)0 });
        addMethod.Invoke(errorCollection, new[] { error });
        var constructor = typeof(SqlException)
            .GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, //visibility
                null, //binder
                new[] { typeof(string), typeof(SqlErrorCollection), typeof(Exception), typeof(Guid) },
                null); //param modifiers
        return (SqlException)constructor.Invoke(new object[] { message, errorCollection, new DataException(), Guid.NewGuid() });
    }

समीक्षा कतार से : मैं आपसे अनुरोध कर सकता हूं कि कृपया अपने उत्तर के आसपास कुछ और संदर्भ जोड़ दें। कोड-केवल उत्तर समझना मुश्किल है। यह पूछने वाले और भविष्य के पाठकों दोनों की मदद करेगा यदि आप अपनी पोस्ट में अधिक जानकारी जोड़ सकते हैं।
आरबीटी

आप स्वयं पोस्ट को संपादित करके इस जानकारी को जोड़ना चाह सकते हैं। जवाब से संबंधित प्रासंगिक जानकारी बनाए रखने के लिए टिप्पणियों की तुलना में पोस्ट बेहतर स्थान है।
आरबीटी

यह अब काम नहीं करता है क्योंकि SqlExceptionइसमें कंस्ट्रक्टर नहीं है और errorConstructorयह शून्य होगा।
इमाद

@ पहले, आपने समस्या को दूर करने के लिए क्या इस्तेमाल किया था?
सासुके उचिहा

0

आप परीक्षण में SqlException ऑब्जेक्ट बनाने के लिए प्रतिबिंब का उपयोग कर सकते हैं:

        ConstructorInfo errorsCi = typeof(SqlErrorCollection).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[]{}, null);
        var errors = errorsCi.Invoke(null);

        ConstructorInfo ci = typeof(SqlException).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(SqlErrorCollection) }, null);
        var sqlException = (SqlException)ci.Invoke(new object[] { "Exception message", errors });

यह काम नहीं करेगा; SqlException में कोई निर्माता नहीं है। @ Default.kramer से उत्तर ठीक से काम करता है।
माइक क्रिश्चियन

1
@ माइक कैरिस्टियन यह काम करता है यदि आप किसी ऐसे कंस्ट्रक्टर का उपयोग करते हैं जो उदाहरण के लिए मौजूद हैprivate SqlException(string message, SqlErrorCollection errorCollection, Exception innerException, Guid conId)
शॉन वाइल्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.