Unit Test-isolation framework and unit test isolation framework

Source: Internet
Author: User

Unit Test-isolation framework and unit test isolation framework

The preceding example describes how to manually create a simulated object. This chapter describes how to create an example using a simulated framework. The simulation framework I use is NSubstitute.

1: How to Create a pseudo object

We know that writing pseudo objects manually is very clumsy (based on the actual situation, of course), so it will be very easy and fast to create pseudo objects using the isolation framework. Let's look at a picture first.

First, create interfaces

1 public interface IUser2 {3 bool Add (string userName, string realName); 4}IUser

Implementation Interface

1 public class User: IUser {2 public bool Add (string userName, string realName) 3 {4 return true; 5} 6}User

Calls in business

1 public class UserManager 2 {3 public bool Add (string userName, string realName) 4 {5 if (string. isNullOrWhiteSpace (userName) throw new ArgumentNullException (userName); 6 if (string. isNullOrWhiteSpace (realName) throw new ArgumentNullException (realName); 7 8 if (userName. length> = 0) 9 {10 return false; 11} 12 return GetUser (). add (userName, realName); 13} 14}UserManager

Unit Test

1 [Test] 2 public void Add_Default_CallAdd () 3 {4 var fakeUser = Substitute. for <IUser> (); 5 fakeUser. add ("1", "1 "). returns (true); // return value 6 Assert as needed. isTrue (fakeUser. add ("1", "1"); 7}Add_Default_CallAdd ()

The preceding two parameters are input and true is returned as needed;

What if we don't consider the parameters?

You only need to set the parameter to Arg. Any <T> ()/T to indicate that the parameter type can be string or int.

Of course, the returned value must be of your predefined type. The return value of bool Add () must be of the bool type or an exception is thrown.

2: usage of When... Do

When do is still widely used in NSub. This is a metaphor for what to do. The following is an example.

1 [Test] 2 public void Add_Default_CallAdd () 3 {4 var fakeUser = Substitute. for <IUser> (); 5 fakeUser. when (x => x. add ("1", "2 ")). 6 Do (content =>{ throw new Exception ("fack exception") ;}); // use the when, do representation, what are the consequences of this function? 7. Assert. throws <Exception> () => fakeUser. add ("1", "2"); 8}When-Do

In the preceding example, an exception is thrown when the parameters are 1 and 2. The following describes the actual results.

If the parameters are 1 and 2, an exception will be thrown. If the values are 1 and 3, an exception will be thrown. manually modify the parameters to see the following results:

As soon as the test is passed, it indicates that an exception will be thrown only when parameters 1 and 2 are used. In this way, the simulation framework also verifies the predefined parameters.

3: Very powerful Received ()

The work of the Received () method is amazing. When an object is called, The method returns an object of the same type as this object, but it is actually the object of the declarative assertions. What do you mean? Let's look at the following code:
For the interfaces and implementation methods in the test, refer to the previous article.

1 [Test] 2 public void RecordLog_EmailServiceThrows_CallEmail () 3 {4 var stub = Substitute. for <ILogService> (); 5 var mock = Substitute. for <IEmailService> (); 6 stub. when (p => p. errorLog (Arg. any <String> ())). do (a =>{ throw new ArgumentNullException () ;}); 7 var test = new TestUserManager (stub, mock); 8 test. recordLog (""); // triggers 9 mock. stored ed (). sendEmail (Arg. is ("lp"), Arg. is ("subject"), Arg. is ("value cannot be Null. "); // Ensure that the method is accepted and called (no more periods are allowed) 10}Test

In the above example, we can see that Received () indicates that SendEmail is called and the message sent by SendEmail is obtained, and then the asserted is consistent with the pre-sent information. This is the same as the simulated object asserted in the previous article. (Do not forget to use the simulated object)

4: How should I test the event?
  • One side of the test listening event
  • Test trigger event party

4.1: Test listening events

Define an event Interface

1 public interface IView2 {3 event Action Loaded; 4 void Render (string content); 5}IView

Event-related code and how to trigger the event

1 public class Presenter 2 {3 4 private readonly IView _ view; 5 6 public Presenter (IView view) 7 {8 this. _ view = view; 9 this. _ view. loaded + = Onload; // register event 10} 11 12 public void Onload () 13 {14 _ view. render ("Hello World"); 15} 16}Presenter

Test code

1 [Test] 2 public void Ctor_WhenViewIsLoad_CallsViewRender () 3 {4 var mockView = Substitute. for <IView> (); 5 var p = new Presenter (mockView); 6 mockView. loaded + = Raise. event <Action> (); 7 8 mockView. stored ed (). render (Arg. is <string> (s => s. contains ("Hello World"); 9 10}Ctor_WhenViewIsLoad_CallsViewRender

Raise. Event indicates the trigger Event.

Finally, use the received command to test whether the Render in the view is triggered. If it is triggered, the accepted parameter is Hello World.

We can simulate a stub to simulate objects one by one.

Modify event-related code

1 public class Presenter 2 {3 4 private readonly IView _ view; 5 private readonly ILogService _ logService; 6 7 public Presenter (IView view, ILogService logService) 8 {9 this. _ view = view; 10 this. _ logService = logService; 11 this. _ view. loaded + = Onload; // register event 12 this. _ view. erroccured + = WriteLog; 13} 14 15 public void Onload () 16 {17 _ view. render ("Hello World"); 18} 19 20 public void WriteLog (string errorContent) {21 _ logService. errorLog (errorContent); 22} 23}Presenter

Test code

1 [Test] 2 public void Ctor_WhenViewIsError_CallsLogs () {3 4 var stubView = Substitute. for <IView> (); 5 var mockLog = Substitute. for <ILogService> (); 6 var p = new Presenter (stubView, mockLog); 7 stubView. erroccured + = Raise. event <Action <string> ("fack error"); 8 mockLog. stored ed (). errorLog (Arg. is <string> (s => s. contains ("fack error"); 9 10}Ctor_WhenViewIsError_CallsLogs

Note: Use the stub stubView. erroccured + = Raise. event <Action <string> ("fack error ");

4.2: test whether the event is triggered

This is relatively simple. Use an anonymous delegate in the test method and manually register the method.

Define a variable. When an event is triggered, change the value of the variable.

For example, bool isTrigger = false;

SomeView = new SomeView ();

SomeView. Load + = delegate {isTrigger = true ;}

SomeView. Trigger the event and check whether the value of isTrigger has changed.

5. Advantages and disadvantages of the simulated framework
  • Advantages
  • Disadvantages

NSubstitute official documentation is very detailed interested can view their own hands-on write a write will have better results http://nsubstitute.github.io/help/raising-events/

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.