(http://www.dotspace.idv.tw/xp/test-driven development IN .Net.htm)
Use Test-Driven Development in .NET environment Test-Driven Development in .NET
Translation preface:
This article
Copyright belongs to the original author. Author website in (http://www.peterprovost.org). This article is available in the original article (http://www.peterprovost.org/test-driven development in .net.pdf).
Translator
Name: Harry Chou (Zhou Yong). Welcome to write Email to Yuheng98@yahoo.com to learn. This article is completely helpless, in addition to this article, I also translated Python Tutorial. Translation is just to review my Chinese expression, but also to the Taiwan soft body.
This paper translate in accordance with the following principles
Original terms such as TDD, TEXTFIXTURE, Attributes, Class, Implement, Interface ... have their cultural context and generating backgrounds, which are exempted from persistent in Chinese translation. If necessary, the original term first appearance will be attached to Chinese translation or explanation. Chinese translations are inevitable, please add more to exercise English reading ability. I know that the difference between Chinese and English literacy is quite different. I also know that English sentences are mostly inverted grammar. This article is a technical article, my purpose is to let the words and words do not hinder Chinese readers' reading habits. To this end, I try to simulate the speaking usage. It is like two programming designers who are discussing technical issues. You probably compute "your class needs a new Method, this Method will return an int", not "your category requires a new method, this method Will pass an integer variable. " (Class, Method, Return is also a translation that everyone has been convinced). Of course, the above principles are personal and evil issues, welcome to criticize advice.
Order
Introduction What is Unit Tests? NUnit Framework (NUnit unit testing framework) Introduction TestFixture Attribute Profile Test Attribute Introduction SetUp & Teardown Attributes profile ExpectedException Attributes Introduction Ignore Attributes Introduction Assertion Class Profile execute your tests using Test-Driven Development (test-driven development method) using Mock Objects (simulated object ) - How do DotNETMOCK Test Business Layer How to Test User Interface Conclusions The resources on other Web
Introduction
Although the program developer writes Unit Tests (unit test) to test the number of books written, most Unit Tests is written in the main program code, after writing. Most of the programmed developers have the same experience. After the main program is written, join the Unit Test is a difficult job, and under the pressure of time is usually the first skipped. step.
This article will introduce Test-Driven Development (TDD, test driver development method), the main purpose is to try to solve this problem, and the programmed developer can write higher quality, complete test code . The method is to reverse the entire program, and write the Unit Tests before writing the main program. TDD is one of the so-called Extreme Programming (XP, Ultimate Draft), which is mentioned in the main Practices (implemented) in the Java camp, has a lot of program developers using TDD, and in the .NET's camp. Stay only in a very small number of articles talk about how to use TDD. What is Unit Tests (unit test)?
According to Ron Jeffries, the so-called Unit Tests is "... Many sections of the program, the purpose of writing these programs is to verify the Classes we wrote" (category) Each Unit Test is responsible for sending a message to a specific class, and the value sent back is the answer expected by the test. "If we use the comparative practice to explain, this paragraph means You write a program, you use this program to test all Classes's Public Interfaces (Public Interface) in your main program. Unit tests is different from the so-called Requirement Tests or Acceptance Tests, the UNIT TEST test focus is to verify the results generated by the Methods (subroutine) you are writing, just the same as you expect.
This is simple, and it may be challenging. First, you must first decide what tools use to write these Unit Tests. Testists typically use some large, complex Test Engine (test engines) to write these Unit Tests with some complex Scripting Languages (scripting languages, narrative languages). This may only be used for professional testers or testing sectors. It is not that applicable for UNIT TESTS written by program developers. In fact, for the general programming designer, what they need is a set of Toolkit, which allows them to use their programs and IDE (development tools) that they have originally developed. To write these Unit Tests.
Most of these years of popular Unit Testing Frameworks (Unit Test Development Framework) are derived from the Unit Test Framework designed by the Kent Beck (XP founder). The background of this Unit Test Framework is specially designed for the first XP project (Chrysler C3 project). This first Framework is written in SMALLTALK and has experienced many times, and it still exists today. After this SmallTalk version of Framework, Kent and Erich Gamma (Design Pattern fans should know who he is in this Framework on JAVA and officially named JUnit. Since then, this Framework began to be revised and applied to each of the different programming languages, including C , VB, Python, Perl, and many different programming languages.
NUNIT FRAMEWORK (NUnit Unit Test Framework)
The NUnit 2.0 discussed herein is a very different version of its ancestors (other Framework). Other XUnit family versions usually have an Base Class (Basic Category), you want to write Test Classes (Test Category) is INHERIT (inherited) from this Base Class. In addition, there is no other way to let you write Unit Tests. Unfortunately, this has a large limit for many programming languages. For example, Java and C # can only allow Single Inheritance (single inheritance). That is, if you want the Refactor (reunion) your Unit Tests program code, you will encounter some restrictions; unless you introduce some complex inheritance hierarchies (category inheritance level). Everything is different after .NET, .net introduced a new concept of new program-Attributes, solved this annoying problem. Attributes allows you to add Metadata on your program code (back data / master data / super profile, descriptor code). In general, Attribute does not affect the implementation of the main program, and its feature adds additional information over your desk code. Attributes is primarily used in Documenting Your Code, but Attributes can also be used to provide additional information about Assembly, other programs have not seen this Assembly, or use this information. This is basically what NUNIT 2.0 is made. In NUnit 2.0, there is a Test Runner Application (responsible for executing UNIT TESTS), this test runner scans you already compile, and knows which classes is Test Classes from Attribute, which Methods is needed. Test Methods executed. The Test Runner uses the .NET's Reflection technology to perform these Test Methods. Because of this, you no longer need to let your test classes inherit your self-called Common base Class. What you need to do is to describe your Test Classes and Test Methods using the correct Attribute. NUNIT offers many different Attributes that allows you to write free to write the Unit Tests you want. These Attributes can be used to define Test fixTures, Test Methods, and Methods for the SETUP and TEARDOWN (Methods). In addition, there are other Attributes to set the expected Exceptions, or require Test Runner skip some Test Method not executing.
TestFixTure Attribute Introduction
TestFixTure Attribute is primarily used on Class, and its role is the function of which Class contains Test Methods that needs to be executed. When you add this attribute in a Class's definition, Test Runner checks the Class to see if this class contains Test Methods.
This section code demonstrates how to use TestFixTure Attribute. (All prices in this article are written with C #, but you should know that NUnit is also used in other .NET program, including VB.NET. See NUNIT's related files.)
namespace UnitTestingExamples {using System; using NUnit.Framework; [TestFixture] public class SomeTests {}} is used TextFixture Attribute another unique class required to meet additional constraints, is the need to have a public default constructor (or does not define any CONSTRUCTOR, this is actually the same meaning).
Introduction to Test Attribute
Test Attribute is primarily used to indicate the method in the text fixture, indicating that this Method needs to be executed by the Test Runner Application. There must be a PUBLIC, and there must be Return Void, and there is no incoming parameter. If these regulations are not met, this Method will not be listed in the Test Runner GUI, and this Method will not be executed when performing the Unit Test.
The program code under the bottom demonstrates the method of using this Attribute:
Namespace UnitTeStingexamples {Using System; Using NUNIT.FRAMEWORK; [TestFixTure] public class sometests {[test] public void testone () {// do something ...}}}
Setup & TEARDOWN Attributes Introduction
When writing Unit Tests, sometimes you need to perform some preparatory or good work before performing each Test Method (or later). Of course, you can write a private Method and call this special method at one of the Test Method or the last side. Alternatively, you can use the SETUP and Teardown Attribute we need to reach the same purpose.
Like the name of these two Attributes, the Method with Setup Attribute will be executed by Test Runner before each Test Method in this textFixture, and the Teardown Attribute's method will be executed at each Test Method. It was then executed by Test Runner. In general, SETUP Attribute and Teardown Attribute are used to prepare some must-have Objects, such as Database Connection, and more.
Examples under the bottom show how to use these two Attributes:
namespace UnitTestingExamples {using System; using NUnit.Framework; [TestFixture] public class SomeTests {private int _someValue; [SetUp] public void Setup () {_someValue = 5;} [TearDown] public void TearDown () {_someValue = 0;} [TEST] public void testone () {// do something ...}}} ExpectedException Attribute
Sometimes, you want your program to produce some specific Exception under certain special conditions. To test the program if the program is expected to generate Exception, you can use a Try..catch program section to catch (capture) this Exception, and then set up a Boolean value to prove that Exception does happen. This method is feasible, but it is too spent. In fact, you should use this ExpectedException attribute to indicate which exception should be generated, as shown in the following example:
namespace UnitTestingExamples {using System; using NUnit.Framework; [TestFixture] public class SomeTests {[Test] [ExpectedException (typeof (InvalidOperationException))] public void TestOne () {// Do something that throws an InvalidOperationException}}}
If the above program is executed, if exception occurs, and this Exception's Type is InvalidOperationException, this TEST will pass the verification. If you expect your program code to generate multiple exception, you can also use multiple ExpectedException Attribute at a time. However, a Test Method should only test one thing, and test multiple functions at a time is not good, you should try to avoid it. In addition, this Attribute does not check the relationship of Inheirtance, that is, if your program code is an Exception that inherits from InvalidOperationException, this TEST is executed, it will not pass verification. In short, when you use this Attribute, you have to specify which type (data type) of the expected Exception is.
Ignore Attributes Introduction
This Attribute is probably not often used, but when it is needed, this Attribute is very convenient. You can use this attribute to indicate a Test Method, called Test Runner when executing, ignore this Method not to execute. Ignore attribute using this method is as follows: namespace UnitTestingExamples {using System; using NUnit.Framework; [TestFixture] public class SomeTests {[Test] [Ignore ( "We're skipping this one for now.")] Public void TestOne () {// do something ...}}}
If you want temporary Comment Out a test method, you should consider using this attribute. This attribute allows you to keep your Test Method, in the execution of Test Runner, will also remind you that this slight Test Method exists.
Introduction to NUnit Assertion Class
In addition to these mentioned above, NUNITs have an important class of CLASS, and you should know how to use. This Class is Assertion Class. Assertion Class provides a range of Static Methods that allows you to verify that the major programs are the same as you expect. The examples below demonstrate how to use Assertion Class:
Namespace UnitTexAmples {Using System; Using NUNIT.FRAMEWORK; [TESTFIXTURE] PUBLIC CLASS SOMETESTS {[TEST] public void testone () {int i = 4; assertion.assertequals (4, i);}}}
(I know that this section is just used by demonstration, but this program should understand what I mean.)
Perform your Tests
Ok, now we have discussed the basic steps and methods of writing Unit Tests, let us see how to do what you wrote. It is actually very simple. There are two Test Runner Applications in NUNIT: one is a window GUI program, one is a console XML program. You can freely choose what you like, basically there is no difference. If you want to use Window GUI's Test Runner App, you only need to execute the program, then tell it what you want to perform the Assembly location of Test Method. This contains Assembly, which you have written Test Methods is the Class Library (or Executable, *. DLL or * .exe) Assembly, which contains Test fixTures mentioned earlier. When you tell Test Runner, Test Runner automatically loads this ASEMBLY, then column all Class and Test Methods on the left column of the window. When you press the 'Run' button, you will automatically perform all listed Test Methods. You can also double the Test Class on the Double Click, or on a Test Method, which will automatically perform only the Class or the Method. Under the way, the window GUI TEST Runner is executed: In some cases, especially if you want to join Unit Testing in your own build script, you probably not use the GUI Test Runner. In this case of this automatic implementation of Build Script, you usually put your build's results on the web page, or write log files to save records, with supplies, managers, or customers, you can learn more by checking this record. Happening. In this case, you can use the Console Test Runner Application of NUnit 2.0. This Test Runner can be passed to the location of Assembly as a parameter, and its test execution result is an XML string. You can convert this XML result into html with XSLT or CSS, or other format you want. If you need this feature, check the NUNIT file for information on the Console Test Runner Application.
Use Test-Driven Development (test drive development method)
Said so much, you already know how to write Unit Tests, right? Ah, like writing, only know the grammar, and there is a large distance from the distance. You also need to learn some skills and methods, so you can truly write professional applications. At the end, we will talk about some skills and methods that help you start, but you have to know that the only way to let you write enough UNIT TESTS only one, practice, practice, and practice.
If you have not heard TDD at all, you will not accept it at what you say. In the past, many programmakers have spent countless time and experience, writing a lot of books and articles, telling us to do the design work before the writer code, and then write the code code, and finally be careful Test if your written program is correct. Ok, forget all this, I will tell you next, it is the full lane-free process mentioned above.
We no longer design, write the code, and then test, we will turn this process throughout the process, write the test code. In another way, we absolutely don't write any rows of major programs, unless we first write test code first, we will implement Test Methods first, first have a test that should not pass verification. That is, the entire writer will become like this: write a Unit Test first. Execute this Unit Test. Of course, this test can not be Compile, because you have not written any main program. (We do this as Test did not pass) Write what you can think of the easiest program code, let your test can compile. Now perform your Unit Test again, you should get the results of the validation failure. (If you have adopted it unfortunate, you said that your Unit Test did not hit the hit, your unit Test is a united Unit Test). Now you can write your main program, let your UNIT TEST can be passed smoothly. Perform your Unit Test again, now your unit Test should have passed smoothly. (If you still don't pass, you should go back to the 5th, check where your program code is wrong, fix it, then execute the Unit Test). Now you can return to step 1 and start writing new features Unit Test!
In fact, when you are in step 5, what you use to write code is just a method of so-called Coding by Intruction (Target, intent). The so-called Coding by Intension is said that your crossing code is written by top. Its relative method is to write up, that is, when you write a section of the program, if you find that the class you are writing, another A class is provided to provide a foo method, then you will jump first A class to write this Method, and then turn your head to write the Class you are writing before. Coding by intention is just the opposite, when you write, you pretend that A class has the foo method you need. When you have written your program to compile, your program should tell you that you have a Class or a Method, which is just the need for Method. As we mentioned before, this is a good thing, the program can't compile and your Unit Test will not pass the same thing.
When you use Coding by Intentions, you clearly express what you want to do. This is not only helping us write the Unit Tests, but also make the program we have written more clear, easy to understand, easy to debug (extension), and program design will also be more improved. In traditional program development methods, tests are only used to help us verify that we have written without errors. But in TDD, Unit Tests can help us define what we want before writing, what we want is what we want, what features should our CLASS should have. I will never say that using TDD will be easier than using a traditional test method, but my experience tells me that the result is indeed contributing to program development.
If you have already heard, I have also read the book about EXTreme Programming, the following program code is just reviewing you already know. If TDD and Extreme Programming are still very strange to you, you can take a look at the following example. Suppose you want to write a program, this program allows your user to save money inside his bank account. Now, according to the principle of TDD, we should start from Unit Test before we write our BankAcount Class. First, let's write our BankAcountTests Class, I think that my BankAcount Class should accept deposits and tell me how much the new balance. I was under the Unit Test code: namespace UnitTestingExamples.Tests {using System; using NUnit.Framework; [TestFixture] public class BankAccountTests {[Test] public void TestDeposit () {BankAccount account = new BankAccount (); account.Deposit ( 125.0); Account.Deposit (25.0); assertion.assertequals (150.0, account.balance);}}}
Now I have written it, I try to COMPILE. Ha, can't compile, of course, I haven't written my BankAcPount Class yet. Now you know, this is the basic principle of Test Driven Development: Unless you have a Unit Test that doesn't pass the verification, don't write any program. Of course, it is not possible to compile whether it is not verified.
Now I can write my bankaccount class, I only have the easiest, most echo code that I can think of, and my purpose is just to make my Unit Test can be compiled:
Namespace UnitTestingExamples.library {Using System; Public Class BankAccount {Public Void Deposit (Double Amount) {} PUBLIC DOUBLE balance {Get {return 0.0;}}}}
Yes, this time is already too close, and then I will use Test Runner to execute my Unit Test. Well, didn't pass, Test Runner told me "TestDeposit: Expected: <150> But Was <0>". (Translator, I don't translate this error message here. After all, this is what you should be able to understand unless you use the Chinese version of NUnit, you will learn that Error Message is necessary). Now, then I will write some program code to make my Unit Test can really verify and generate the results I want:
namespace UnitTestingExamples.Library {using System; public class BankAccount {private double _balance = 0.0; public void Deposit (double amount) {_balance = amount;} public double Balance {get {return _balance;}}}} OK, now I The Unit Test is cleared, I can carry out the next step. (Translators, in fact, according to the EXTreme Programming or the Kent Beck book, you should first take the REFAACTORING (reunion).
Use Mock Objects - DotNETMOCK
When you are writing Unit Test, you will encounter some challenges, one is to make sure every Test Method has only a single feature in a single test. However, under the general case, your Test Method's functionality to test often rely on other Objects to execute their features. Now, if your Test Method tests this feature, you really test is not just this feature, you also tested additional Class.
If this is a problem, you can use Mock Objects to help you disappear out the features you really want to test. The so-called Mock Object, its main function is to simulate other Object, so that you can test this analog Object is not as expected. More importantly, using Mock Objects has the following benefits:
It can be easily written easy to prepare the result that you want to execute the speed. The result is expected to let you verify that an Object does correctly call the call's method, and whether it is in accordance with the correct order Call these Methods.
The following program example demonstrates a typical MOCK Object usage example. Please note that the Unit Test is now clearer, easier to understand, and executing this test will only test the program of the test we want to test, and will not involve unpryngeable Objects.
namespace UnitTestingExamples.Tests {using DotNetMock; using System; [TestFixture] public class ModelTests {[Test] public void TestSave () {MockDatabase db = new MockDatabase (); db.SetExpectedUpdates (2); ModelClass model = new ModelClass (); Model.save (db); db.verify ();}}}
As shown above, the preparation for using this MockDatabase Class is easy, and it is easy to verify that the Method Class is called MockDatabase Class. Using this Mock Object also allows us to worry about whether the real database is working properly. Our only known, that is when this modelclass object is executing this action, it will call the Update Method of the Database object during it. Our UNIT TEST is to verify that there is really call Update Method twice. So let's tell MockDatabase Object We expect UPDATE METHOD to be called twice, then we execute model.save (), and finally verify its results. Because MockDatabase does not involve the issue of linking the database, we don't need to worry that the database will be modified because of the execution test, or how to prepare a valid test information, ... such problems. The only thing we need to care is whether Save Method really causes Update to be called twice. .
(When you use Mock Objects, only your Unit Test and the program you want to test are real things. 引 引 e e-文 一
How to test Business Layer
Test your Business Layer program code, is the most common example of the general program when talking about UNIT TEST. If you carefully plan and design your Business Layer, your Business Layer should be loosely coupled (independent with other parts) and highly cohesive. For practical terms, the so-called coupling refers to your Class and other classes dependent on each other. If coupling is, if we want to modify some Class, we don't need to worry about others. The functionality of the Class will be affected. From another point of view, the so-called Cohrsive is that your Class should only be responsible for a single task, and should not join other incompletely coherent features.
If your Business Layer Class Library is Loosely Coupled and Highly Conhesive, you want to write Unit Test should be a light. You should be able to write a Unit Test Class for each Business Class (Class in Business Layer), and you should easily write corresponding tests for each Business Class's public methods.
Yes, if you find that you want to write Unit Test for your Business Class, you have found difficulties, you might want to consider the work of the REFAAAANG (renewal) of the big landscape. Of course, if you write Unit Tests to write business classes, you should not fall into this point.
How to test User Interface (User interface)
When you start the program code of the user interface (user interface), there are some questions to start running. Of course, you can find a way to let your user interface meet the requirements of Loosely Couple, so that it does not rely on other Class. However, the so-called User Interface is essentially from the user and needs to be driven and verified by the user. So, how to solve this problem in the end, let us test our user interface? The key to this answer is that we should carefully distinguish the so-called Logic (logic executed), and so-called user interface (to display data), so that the user interface is only responsible for displaying View. The work of the video / viewpoint). There are many Pattern (design patterns) to help us do this work, their names are endless (Model-View-Presenter, Doc-view, etc.), but are the same purpose. The founders of these Pattern are deeply recognized, and the logic (that is, Controller) to do the logic (that is, Controller) is a very helpful thing.
So how do we use these pattern to help us write Unit Test to test user interface? The skills I have shown here are article from the Humble Dialog Box written by Michael Feathers. In essence, this tip is to let your view class (that is, User Interface Class) IMPLEMENT (implemented) a simple interface. This interface defines the information that this View Class should display, and has getting / setting methods (Metods for accessing materials). Your View Class should only be responsible for displaying the information to the user. When the user has made some action (for example, pressing a button), the responsibility of the Event Handler in the View class is single-handed this action to Controller. Treatment.
We look more clearly in one example. Suppose we have to write a program, one of the windows is to allow the user to type its own name and Social Security Number (Social Security Number, similar to ID card). Both of these two fields must be completed, so we need to check if the user enters the name, and whether the social security number meets the correct format. Since we should write the test code first, we must follow our rules:
[TestFixture] public class VitalsControllerTests {[Test] public void TestSuccessful () {MockVitalsView view = new MockVitalsView (); VitalsController controller = new VitalsController (view); view.Name = "Peter Provost"; view.SSN = "123-45 -6789 "; Assertion.Assert (controller.OnOk () == true);} [Test] public void TestFailed () {MockVitalsView view = new MockVitalsView (); VitalsController controller = new VitalsController (view); view.Name =" "; View.ssn =" 123-45-6789 "; view.sexpectederrorMessage (controller.Error_Message_bad_name); assertion.assert (controller.Anok () == false; view.verify (); view.name =" Peter Provost "; View.ssn =" "; view.sexpectederrorMessage (controller.Error_Message_bad_ssn); assertion.Assert (Controller.Anok () == false); view.verify ()}} If you try to compile and build this test program Code, you will see a lot of error messages. Don't be nervous, this is because we have not started writing MockVitalSView and the two Class of VitalScontroller. Ok, let's write the original architecture of these two classes now. Remember our rules, we only need to write the easiest, you can compile, the code code:
public class MockVitalsView {public string Name {get {return null;} set {}} public string SSN {get {return null;} set {}} public void SetExpectedErrorMessage (string message) {} public void Verify () {throw new NotImplementedException ();}} public class VitalsController {public const string ERROR_MESSAGE_BAD_SSN = "Bad SSN."; public const string ERROR_MESSAGE_BAD_NAME = "Bad name."; public VitalsController (MockVitalsView view) {} public bool OnOk () {return false;}} call out! Now our UNIT TEST has successfully compiled, let's try to see if these Unit Tests can verify. puff! Test Runner tells us that there are two Tests without verification. The first is when calling Controller.Onok inside TestSuccess, because the result of the back is False, not what we expect. The second place is when calling View.verify inside TestFailed.
We continue to follow the principles of our first write test code, now we need to find a way to make our unit tests can pass smoothly. If you just want TestSuccessful through, you have to write some of the truly useful program. For example, like this:
public class MockVitalsView: MockObject {public string Name {get {return _name;} set {_name = value;}} public string SSN {get {return _ssn;} set {_ssn = value;}} public string ErrorMessage {get {return _expectedErrorMessage .Actual;} set {_expectedErrorMessage.Actual = value;}} public void SetExpectedErrorMessage (string message) {_expectedErrorMessage.Expected = message;} private string _name; private string _ssn; private ExpectationString _expectedErrorMessage = new ExpectationString ( "expected error message") ;} public class VitalsController {public const string ERROR_MESSAGE_BAD_SSN = "Bad SSN."; public const string ERROR_MESSAGE_BAD_NAME = "Bad name."; public VitalsController (MockVitalsView view) {_view = view;} public bool OnOk () {if (IsValidName ( ) == false) {_View.ErrorMessage = ERROR_MESSAGE_BAD_NAME; return false;} if (IsValidSSN () == false) {_view.ErrorMessage = ERROR_MESSAGE_BAD_SSN; return false;} // All is well, do something ... return true;} private bool IsValidName () {return _view. Name.length> 0;} private bool isvalidssn () {string pattern = @ "^ / d {3} - / d {2} - / d {4} $"; return regex.ismatch (_View.ssn, pattern) } Private mockvitalsview _View;}
Before we continue, let's stop watching this section code first. First of all, we have not even fade until we start writing the Unit Test program (this is why I didn't put them on the above reason). What we have greatly moved is on MockVitalSview and VitalScontroller. Let's take a look at MockVitalSview. In our previous example, MockVitalSView did not inherit any Base Class. Now in order to simplify our work, we turn it into inheritance from DotNetMock.mockObject. This MockObject Class gives us a Verify Method, this Method made all our work. The magical power it has comes from Expectation Classes. We use the Expectation Class to set the things we expect Mock Object. In this example, we expect ERRORMESSAGE this Property a specific value. Because this property is a String data type, we joined a Member called Expectationstring inside our Mock Object. Next we wrote the two Method and Property of ErrorMessage, let them use this Expectationstring Object. When we call Verify in our test code, the MockObject base Class automatically checks whether the results we expect will happen and inform us where it is inconsistent with expectations. Cool. is not it?
Another bigger is more than our VitalScontroller Class. Because this is all the programs that really have worked, we know that it is inevitable. Basically, our main logic, the main program code is on the Onok this Method. Here, we use our View Class to read the data of the data to read the information filled out by the user, and then if the information is not met, we use the ErrorMessage this property to pass the error message back.
So, our work has been coming to a paragraph? Early yard. So far, we are just in the Controller, we are just using analog Mock View to pretend that we have a USER Interface. In fact, we have nothing to show users yet! Don't be nervous, we need it now just let us write a good Controller, you can connect to the real view. How to do it?
First, we need to grab it from the IMPLEMENT of MockVitalSView. If we look at the programs of VitalScontroller and VitalSControllertes, we can find that this Interface under the bottom should meet our needs:
Public interface {get; set; set;} string errorMessage} string errorMessage} string errorMessage} string errorMESSAGE
We have the new Interface we want, now we can use the program code of the MockVitalSview in Controller, change to use IVITALSVIEW. Then we can modify MockVitalSView, let it imports this iVitalSView. Of course, after we do this refactoring action, we have to hurry to do our UNIT TEST, make sure we have not made any stupid things. Suppose everything is normal, all the tests have passed, we can really start to write View. In this example I use the ASP.NET web page to make our view, you should know that you can easily write a Windows Form's View. Under the bottom is our .aspx file:
! <% @ Page language = "c #" Codebehind = "VitalsView.aspx.cs" AutoEventWireup = "false" Inherits = "UnitTestingExamples.VitalsView"%>