jeudi 31 mars 2016

How to test textbox component in asp.net using mvp pattern using NSubstitute, C#?

I'm learning mvp pattern and unit tests in asp.net web forms. I created sample to try make a simple test of textbox component. There is only one form 'Home.aspx' with textbox named 'QuestionContent' and one button named 'SendQuestion'. The code-behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication12
{
    public interface IHomeView
    {
        string QuestionContent_Text { get; set; }
    }

    public partial class Home : System.Web.UI.Page,IHomeView
    {
        private HomePresenter _homePresenter;

        public Home()
        {
            _homePresenter = new HomePresenter(this);
        }

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        public string QuestionContent_Text
        {
            get
            {
                return QuestionContent.Text;
            }
            set
            {
                QuestionContent.Text = value;
            }
        }

        protected void SendQuestion_Click(object sender, EventArgs e)
        {
            if (QuestionContent_Text.Count() > 30)
            {
                _homePresenter.SendQuestion_Click();
            }
        }
    }
}

I created presenter class in other file. The code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication12
{
    public interface IHomePresenter
    {
        bool SendQuestion_Click();
    }

    public class HomePresenter : IHomePresenter
    {
        private IHomeView _homeView;

        public HomePresenter(IHomeView homeView)
        {
            this._homeView = homeView;
        }

        public bool SendQuestion_Click()
        {
            //..some code, if sth gone wrong return false

            //message send successfully
            return true;
        }
    }
}

I Created project Unit Test Project. I created class 'HomeTest'. Here is the code:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using NSubstitute;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WebApplication12.Tests
{
    [TestClass]
    public class HomeTest
    {

        private HomePresenter _homePresenter;
        private IHomeView _homeView;


        public void Init()
        {
            Home HomeMock = Substitute.For<Home>();

            _homeView = (IHomeView)HomeMock;
            _homePresenter = new HomePresenter(_homeView);
        }

        [TestMethod]
        public void CheckIfMessagePassedValidationAndSentProperly_GivenSampleText31Length_ReturnsTrue()
        {
            Init();


            bool result=false;

            _homeView.QuestionContent_Text = "0123456789001234567890012345678901"; //length=31

            if (_homeView.QuestionContent_Text.Count() > 30)
            {
                result = _homePresenter.SendQuestion_Click();
            }

            Assert.IsTrue(result);

        }
    }
}

I created method to test if length of QuestionContent textbox content is greater than 30. If yes invoke _homePresenter.SendQuestion_Click() method. When I run test method I get error: "Object reference not set to an instance of an object." on line of code

_homeView.QuestionContent_Text = "0123456789001234567890012345678901"; 

My first thought was to add TextBox QuestionContentControl { set; } to IHomeView, then implement it in Home class:

 public TextBox QuestionContentControl
 {
    set
    {
        QuestionContent = value;
    }
 }

and then create mock in my test method:

_homeView.QuestionContentControl = Substitute.For<TextBox>();

I implemented that solution and all worked properly but I dont think it is a good practise cuz I won't use public TextBox QuestionContentControl in my production code. I will use it only for tests. Can somebody tell me if I'm right with my suggestion that create public TextBox QuestionContentControl is not a good practise and give me an alternative how to make test to CheckIfMessagePassedValidationAndSentProperly ?

Aucun commentaire:

Enregistrer un commentaire