2009-06-19 15 views
15

मैं यूनिट परीक्षण के लिए नया हूं और मैं अपनी कुछ .NET सदस्यता सामग्री का परीक्षण करने की कोशिश कर रहा हूं।यूनिट टेस्ट Asp.net सदस्यता कैसे करें?

तो मैं अपने VerifyUser विधि को जांचने की कोशिश कर रहा हूं जो जांचता है कि उपयोगकर्ता प्रमाण-पत्र मान्य हैं या नहीं।

public bool VerifyUser(string userName, string password) 
    { 
     bool valid = Membership.ValidateUser(userName, password); 
     return valid; 
    } 

और अब हर बार मैं अपने इकाई परीक्षण यह विफल चलाएँ:

तो यह कि यह दिखता है। मुझे पता है कि मैं सही प्रमाण-पत्र और सामान में गुजर रहा हूं। फिर यह मेरे सामने आया कि शायद मेरी टेस्ट प्रोजेक्ट (जो कि मेरे वास्तविक प्रोजेक्ट के समान समाधान के तहत है) को कनेक्शन स्ट्रिंग और सामान के साथ अपनी web.config फ़ाइल की आवश्यकता हो सकती है। या एक ऐप कॉन्फ़िगरेशन फ़ाइल हो सकता है क्योंकि यह एक एप्लिकेशन लाइब्रेरी प्रोजेक्ट है।

तो क्या मैं बस अपनी वास्तविक परियोजना से web.config फ़ाइल कॉपी करता हूं और इसे एक दिन कॉल करता हूं? या मुझे केवल इससे भाग लेना चाहिए? या मैं बस रास्ता बंद कर रहा हूँ।

मेरा डेटाबेस मेरे डेटाबेस के साथ विलय सदस्यता के साथ एक कस्टम डेटाबेस का उपयोग कर रहा है। तो मेरी कॉन्फ़िगरेशन फ़ाइल में मुझे एक प्रबंधक प्रदाता और एक भूमिका प्रदाता निर्दिष्ट करना था।

:

यह

तरह
[Test] 
    public void TestVerifyUser() 
    { 
     AuthenticateUser authenitcate = new AuthenticateUser(); 
     bool vaild = authenitcate.VerifyUser("chobo3", "1234567"); 


     Assert.That(vaild, Is.True); 
    } 

इसके अलावा बाद में मैं अपने asp.net MVC के ActionResult तरीके से एक में है (लॉग देखें सटीक होना करने के लिए) कैसे मेरे इकाई परीक्षण लग रहा है मैं इस किया है फॉर्म प्रमाणीकरण। रीडायरेक्टफ्रॉम लॉग इन पेज (लॉगिन वैलिडेशन.उसरनाम, याद रखें);

तो अब मैं एक यूनिट टेस्ट कैसे लिख सकता हूं जो उपयोगकर्ता करेगा जो करेगा। मान लें कि वे होम पेज पर शुरू होते हैं और फिर लॉगिन पेज पर क्लिक करते हैं और सफलतापूर्वक लॉग इन करते हैं। मैं उन्हें होम पेज पर रीडायरेक्ट करना चाहता हूं।

मुझे यकीन नहीं है कि कोड में इसका प्रतिनिधित्व कैसे किया जाए। मुझे पूरा यकीन है कि RedirectFromLoginPage काम करता है और अब मैं वास्तव में परीक्षण कर रहा हूं। मैं इस तथ्य का परीक्षण कर रहा हूं कि मेरे पास 3 चीजें हैं जो लॉगिन ActionResult विधि में हो सकती हैं।

  1. उपयोगकर्ता लॉग इन करता है और कहां से आया है उसे वापस भेज दिया जाता है।
  2. उपयोगकर्ता लॉगिन करने में विफल रहता है और LoginView पर वापस भेज दिया जाता है और त्रुटि संदेश देखता है।
  3. उपयोगकर्ता ने सुरक्षित पर जाने की कोशिश की है और लॉगिन पेज पर रीडायरेक्ट कर दिया गया है। अगर लॉगिन सफलतापूर्वक रिटर्न यूआरएल के माध्यम से सुरक्षित पृष्ठ पर रीडायरेक्ट किया जाएगा।

तो मैं देखने के लिए अगर इन काम के रूप में वे चाहिए एक परीक्षण करना चाहते हैं। तो यही कारण है कि मुझे उपयोगकर्ता को होम पेज की तरह आने की आवश्यकता है ताकि यह देखने के लिए कि क्या उन्हें बाद में रीडायरेक्ट किया गया है और यदि वे एक सुरक्षित पृष्ठ से आते हैं तो वे बाद में उस पर रीडायरेक्ट हो जाते हैं।

मैं एनयूनिट 2.5 और वीएस -2008 प्रो का उपयोग करके भी हूं।


यही वह है जिसे मैं परीक्षण करने की कोशिश कर रहा हूं। मैं उस हिस्से में हूं जहां मैं यह देखने की कोशिश कर रहा हूं कि उपयोगकर्ता मान्य है या नहीं (अगर कथन)। मुझे इसका कोई परीक्षण नहीं है कि इसका परीक्षण कैसे किया जाए।

public ActionResult Login(string returnUrl, FormCollection form, bool rememberMe) 
     { 
      LoginValidation loginValidation = new LoginValidation(); 
      try 
      { 
       UpdateModel(loginValidation, form.ToValueProvider()); 

      } 
      catch 
      { 

       return View("Login"); 
      } 

      if (ModelState.IsValid == true) 
      { 

       bool valid = authenticate.VerifyUser(loginValidation.UserName, loginValidation.Password); 

       if (valid == false) 
       { 
        ModelState.AddModelError("frm_Login", "Either the Password or UserName is invalid"); 

       } 
       else if (string.IsNullOrEmpty(returnUrl) == false) 
       { 
        /* if the user has been sent away from a page that requires them to login and they do 
        * login then redirect them back to this area*/ 
        return Redirect(returnUrl); 
       } 
       else 
       { 

        FormsAuthentication.RedirectFromLoginPage(loginValidation.UserName, rememberMe); 
       } 

      } 


      return View("Login"); 
     } 

उत्तर

7

तुम एक दो परतों में अपने कस्टम सदस्यता कोड पुनर्रचना करके अपने नियंत्रकों का परीक्षण करने और अपने कस्टम प्रदाता के ज्यादा कर सकते हैं सदस्यता एपीआई सेवा परत वह जगह है जहां आप EnablePasswordReset जैसे पैरामीटर को मान्य, रोक और लागू करते हैं और किसी भी डेटाबेस अपवाद या स्थिति कोड का अनुवाद नियंत्रक खपत के लिए उपयुक्त रूप में करते हैं।

जब आप प्रत्येक परत को अपने इंटरफ़ेस के साथ निर्दिष्ट करते हैं, तो उपभोक्ता इस इंटरफ़ेस को लिख सकते हैं कि इसके कार्यान्वयन के बावजूद। जब आपका ऐप चल रहा है तो आपका प्रदाता इन इंटरफेस के माध्यम से डेटाबेस से बात कर रहा है लेकिन परीक्षण के लिए आप रिपोजिटरी या सर्विस इंटरफेस का नकल कर सकते हैं। आप डेटाबेस या web.config फ़ाइल के साथ गड़बड़ किए बिना रिपोजिटरी स्तर पर नकल करके अपनी सेवा परत का परीक्षण कर सकते हैं, और आप सेवा परत को मजाक कर अपने नियंत्रकों का परीक्षण कर सकते हैं। यदि आप पूरे प्रदाता को दोबारा नहीं बदलना चाहते हैं, तो आप अभी भी अपने नियंत्रकों का परीक्षण कर सकते हैं यदि आप केवल सेवा इंटरफ़ेस बनाते हैं और आपके नियंत्रक इसका उपयोग करते हैं।

, विशिष्ट होना करने के लिए एक छोटे से वर्बोज़, अपने भंडार और सेवा इंटरफेस कुछ लग सकता है अगर की तरह:

namespace Domain.Abstract { 
    public interface IRepository { 
     string ConnectionString { get; } 
    } 
} 

namespace Domain.Abstract { 
    public interface IUserRepository : IRepository { 
     MembershipUser CreateUser(Guid userId, string userName, string password, PasswordFormat passwordFormat, string passwordSalt, 
       string email, string passwordQuestion, string passwordAnswer, bool isApproved, 
       DateTime currentTimeUtc, bool uniqueEmail); 
     MembershipUser GetUser(Guid userId, bool updateLastActivity, DateTime currentTimeUtc); 
     PasswordData GetPasswordData(Guid userId, bool updateLastLoginActivity, DateTime currentTimeUtc); 
     void UpdatePasswordStatus(Guid userId, bool isAuthenticated, int maxInvalidPasswordAttempts, int passwordAttemptWindow, 
         DateTime currentTimeUtc, bool updateLastLoginActivity, DateTime lastLoginDate, DateTime lastActivityDate); 
     //.... 
    } 
} 

namespace Domain.Abstract { 
    public interface IUserService { 
    bool EnablePasswordRetrieval { get; } 
    bool EnablePasswordReset { get; } 
    bool RequiresQuestionAndAnswer { get; } 
    bool RequiresUniqueEmail { get; } 
    //.... 

    MembershipUser CreateUser(string applicationName, string userName, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved); 
    MembershipUser GetUser(Guid userId, bool userIsOnline); 
    bool ValidateUser(Guid userId, string password); 
    //... 
    } 
} 

namespace Domain.Concrete { 
    public class UserService : IUserService { 
    private IUserRepository _userRepository; 


    public UserService(IUserRepository userRepository) { 
     _userRepository = userRepository; 
    } 
    //... 
    public bool ValidateUser(Guid userId, string password) { 
     // validate applicationName and password here 
     bool ret = false; 
     try { 
      PasswordData passwordData; 
      ret = CheckPassword(userId, true, true, DateTime.UtcNow, out passwordData); 
     } 
     catch (ObjectLockedException e) { 
      throw new RulesException("userName", Resource.User_AccountLockOut); 
     } 
     return ret; 
    } 

    private bool CheckPassword(Guid userId, string password, bool updateLastLoginActivityDate, bool failIfNotApproved, 
           DateTime currentTimeUtc, out PasswordData passwordData) { 
     passwordData = _userRepository.GetPasswordData(userId, updateLastLoginActivityDate, currentTimeUtc); 

     if (!passwordData.IsApproved && failIfNotApproved) 
      return false; 

     string encodedPassword = EncodePassword(password, passwordData.PasswordFormat, passwordData.PasswordSalt); 
     bool isAuthenticated = passwordData.Password.Equals(encodedPassword); 

     if (isAuthenticated && passwordData.FailedPasswordAttemptCount == 0 && passwordData.FailedPasswordAnswerAttemptCount == 0) 
      return true; 
     _userRepository.UpdatePasswordStatus(userId, isAuthenticated, _maxInvalidPasswordAttempts, _passwordAttemptWindow, 
              currentTimeUtc, updateLastLoginActivityDate, 
              isAuthenticated ? currentTimeUtc : passwordData.LastLoginDate, 
              isAuthenticated ? currentTimeUtc : passwordData.LastActivityDate); 

     return isAuthenticated; 
    } 
} 
1

दुर्भाग्य से आप बस अपने web.config या अपने app.config कॉपी नहीं कर सकते और यह कि जिस तरह से काम किया है। इसका कारण यह है कि आपकी असेंबली एनयूनीट प्रक्रिया के अंदर चल रही है, न कि आपके आवेदन के तहत।

अपनी स्थिति का समाधान करने के लिए, आपको शायद उन सदस्यों के सदस्यों को मॉक करना या स्टब करना होगा, जिन्हें आप अपने वेब.कॉन्फिग में संग्रहीत सेटिंग्स में कॉन्फ़िगरेशन दृष्टिकोण पर कॉन्फ़्रेंस का पालन करना चाहते हैं।

कई मजाक चौखटे वहाँ एक जोड़े हैं, लेकिन यहाँ: Rhino Mocks, Moq

इसके अलावा, कन्वेंशन विन्यास से अधिक दृष्टिकोण का पालन करने के लिए, आप कुछ इस तरह कर सकता है:

static ConfigurationSettings 
{ 
    static String SomeSetting 
    { 
     get 
     { 
      var result = "HARDCODEDVALUE"; 
      if (ConfigurationManager.AppSettings["SOMEKEY"] != null) 
       result = ConfigurationManager.AppSettings["SOMEKEY"]; 
      return result; 
    } 
} 

आप इसके बाद इस कोड का उपयोग इस प्रकार कर सकते हैं:

//this is how the old code might look 
var mySetting = ConfigurationManager.AppSettings["SOMEKEY"]; 
//use the setting 

//this is how the new code would look 
var mySetting = ConfigurationSettings.SomeSetting; 
//use the setting 

इस प्रकार आपका परीक्षण काम करेगा, और जब आप इसे अपने एप्ली के तहत चलाएंगे cation यह आपके द्वारा संग्रहीत किए गए कॉन्फ़िगरेशन सेटिंग्स का उपयोग करेगा।

+0

माफ करना, मैं मैं में मजाक के बारे में पढ़ा "विन्यास दृष्टिकोण से अधिक सम्मेलन" समझ में नहीं आता किताब मेरे पास है।इंटरफेस या ऐसा कुछ इस्तेमाल करने के साथ इसका कुछ करना है? मुझे यह लिंक मिला लेकिन मुझे लगता है कि यह मेरे लिए काम नहीं करेगा क्योंकि मैं नुनिट का उपयोग कर रहा हूं और वह MbUnit का उपयोग कर रहा है? http://aspalliance.com/1590 – chobo2

+0

@ chobo2 मैं इसका उपयोग कैसे करें इसके बारे में कुछ डालूंगा। मॉकिंग फ्रेमवर्क निश्चित रूप से इंटरफेस का उपयोग करने और अच्छे कारण के लिए एक पतला है। इंटरफेस का उपयोग करना अच्छा decoupling प्रदान करता है। हालांकि, आपको सभी मॉकिंग फ्रेमवर्क में इंटरफेस का उपयोग करने की आवश्यकता नहीं है। इसके अलावा, NUnit और MbUnit कई तरीकों से समान हैं, इसलिए एमबीयूनीट में जो कुछ किया जाता है, वह संभवतः न्यूटिट के साथ एक समानता है। कुछ शोध करने लायक है। – Joseph

+0

ठीक है धन्यवाद। मैं अभी भी इंटरफेस को वास्तव में समझ नहीं पा रहा हूं और यूनिट परीक्षण की बात करते समय वास्तव में उनके साथ नहीं सोचा है। तो उम्मीद है कि इन ढांचे में से एक इसे थोड़ा आसान बना देगा। आप किसकी सिफारिश करते हैं? मुझे लगता है कि "Moq" linq sytanx का उपयोग करता है, इसलिए मुझे यकीन नहीं है कि अगर उस बल्ले का अधिकार है तो यह मेरे लिए अच्छा होगा क्योंकि मुझे linq के बारे में बहुत कुछ पता नहीं है। यह ढांचे नुनिट के साथ कैसे काम करते हैं? जैसा कि मैं अभी भी अपना परीक्षण चलाने के लिए ननिट का उपयोग करता हूं या क्या? – chobo2

3

Asp.Net सदस्यता प्रणाली को Asp.Net अनुरोध के संदर्भ में काम करने के लिए डिज़ाइन किया गया है। तो, आपके पास तीन विकल्प हैं।

  1. अधिकांश लोग इस तरह की निर्भरता का सामना करते समय इसके आसपास एक पतली आवरण लिखेंगे। रैपर कुछ भी नहीं करता है, बस सभी कॉल को अंतर्निहित निर्भरता पर रीडायरेक्ट करता है। तो, वे बस इसका परीक्षण नहीं करते हैं। आपका प्रमाणीकरण उपयोगकर्ता ऐसा रैपर है। आपको संभवतः सभी विधियों को वर्चुअल बनाने या इंटरफ़ेस निकालने के लिए इसे मॉक करने योग्य बनाने के लिए करना चाहिए, लेकिन यह एक और कहानी है।
  2. टाइपमैक आइसोलेटर और नकली सदस्यता का उपयोग करें।
  3. Ivonna framework का उपयोग करें और अपने परीक्षण को Asp.Net संदर्भ में चलाएं (यह एकीकरण परीक्षण होगा)। एक डेटा का उपयोग भंडार है कि केवल डाटाबेस के साथ सूचना का आदान प्रदान, और एक सेवा परत भंडार घटकों का उपयोग करता है प्रदान करने के लिए:
संबंधित मुद्दे