zoukankan      html  css  js  c++  java
  • 为Asp.net控件写单元测试(ViewState)

     

    通常一个典型的asp.net控件至少会用ViewState存储一些属性,以便于在页面postback后不用重新设置。在这篇文章里我将介绍如何为控件写单元测试,以确保一个属性被正确的保存在ViewState里。

    为了演示,我写了一个简单的控件。

    namespace Eilon.Sample.Controls {
    using System;
    using System.Web.UI;
    public class NewLabel : Control {
    public string Text {
    get {
    string s = ViewState["Text"] as string;
    return s ?? String.Empty;
    }
    set {
    ViewState["Text"] = value;
    }
    }
    protected override void Render(HtmlTextWriter writer) {
    writer.Write(Text);
    }
    }
    }

    这个控件只是简单的将它唯一的属性Text输出。

    好的,让我们写一个简单的单元测试,以确保这个控件正确的工作。

    namespace Eilon.Sample.Controls.Test {
    using System;
    using System.IO;
    using System.Web.UI;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    [TestClass]
    public class NewLabelTest {
    [TestMethod]
    public void TextReturnsEmptyStringDefault() {
    NewLabel label = new NewLabel();
    Assert.AreEqual<string>(String.Empty, label.Text,

    "Default text should be empty string (not null)");
    }
    [TestMethod]
    public void GetSetText() {
    const string value = "Some Text";
    NewLabel label = new NewLabel();
    label.Text = value;
    Assert.AreEqual<string>(value, label.Text,

    "Property value isn't the same as what we set");
    }
    [TestMethod]
    public void RenderEmpty() {
    NewLabel label = new NewLabel();
    Assert.AreEqual<string>(String.Empty, GetRenderedText(label),

    "Shouldn't have rendered anything");
    }
    [TestMethod]
    public void RenderWithText() {
    const string value = "Some Text";
    NewLabel label = new NewLabel();
    label.Text = value;
    Assert.AreEqual<string>(value, GetRenderedText(label),

    "Should have rendered the text");
    }
    private static string GetRenderedText(Control c) {
    HtmlTextWriter writer = new HtmlTextWriter(new StringWriter());
    c.RenderControl(writer);
    return writer.InnerWriter.ToString();
    }
    }
    }

    看上去我们已经覆盖了100%的代码,是这样吗?事实上我们根本不能保证这个控件的属性已经被正确的存储到ViewState里了。可是我们知道与ViewState有关的函数都是protected的,并不能从外部访问。解决这个问题,可以有很多办法,这里我们写一个internal interface

    // Interface to expose protected methods from
    // the Control class to our unit test
    internal interface IControl {
    void LoadViewState(object savedState);
    object SaveViewState();
    void TrackViewState();
    }
    然后让我们的控件去实现它:

    #region IControl Members
    void IControl.LoadViewState(object savedState) {
    LoadViewState(savedState);
    }
    object IControl.SaveViewState() {
    return SaveViewState();
    }
    void IControl.TrackViewState() {
    TrackViewState();
    }
    #endregion

    现在就可以测试ViewState了:

    [TestMethod]
    public void TextSavedInViewState() {
    // Create the control, start tracking viewstate,
    // then set a new Text value
    const string firstValue = "Some Text";
    const string secondValue = "ViewState Text";
    NewLabel label = new NewLabel();
    label.Text = firstValue;
    ((IControl)label).TrackViewState();
    label.Text = secondValue;
    // Save the control's state
    object viewState = ((IControl)label).SaveViewState();
    // Create a new control instance and load the state
    // back into it, overriding any existing values
    NewLabel newLabel = new NewLabel();
    label.Text = firstValue;
    ((IControl)newLabel).LoadViewState(viewState);
    Assert.AreEqual<string>(secondValue, newLabel.Text,
    "Value restored from viewstate does not match the original value we set");
    }

    这里注意一点,我们的接口是internal的,为了让测试用例可以访问它,需要添加

    using System.Runtime.CompilerServices;
    [assembly: InternalsVisibleTo("MyControlLibrary.Test")]

     

     

     

     

     

     

     

  • 相关阅读:
    mysql学习总结(四)
    mysql学习总结(三)
    mysql学习总结(二)
    mysql学习总结
    学习总结(三十)
    断点续传
    错误总结
    学习总结(三十六)
    学习总结(三十五)
    Linux命令
  • 原文地址:https://www.cnblogs.com/osamede/p/771944.html
Copyright © 2011-2022 走看看