This article collects some problems and solutions encountered during unit testing for your reference.
How do I check whether the returned collection class meets the expectation?
Microsoft UnitTestFramework |
Use CollectionAssert. AreEqual if the order of elements is the same. Use CollectionAssert. AreEquivalent if you do not need to consider the order. (In some cases, the Assert. AreEqual of MSTest supports the comparison of set types. I tested it and fooled people) |
NUnit |
Same as above |
XUnit |
The Assert. Equal (c1, c2) of xUnit supports the comparison of set types. The element sequence of c1 and c2 must be consistent. |
Which framework is more suitable for Microsoft UnitTestFramework/nUnit/xUnit?
Microsoft UnitTestFramework and nUnit are very similar in usage, while xUnit is more concise because it draws on nUnit design experience. The following are two articles written by Zhou Gong. nUnit and xUnit are very detailed. You can read them:
- Unit test tool in. NET development (1) -- NUnit
- Unit test tool in. NET Development (2) -- xUnit. Net
What is Mock?
The objective of unit testing is to verify only one method at a time. small steps are taken forward and fine-grained tests are conducted. However, if a method depends on some other difficult tasks, for example, network connection, database connection, system time, or Servlet container, what should we do? What if your test depends on other parts of the system, or even multiple parts of the system? In this case, if you are not careful, you may eventually find that you have initialized almost every component of the system, this is just to create enough runtime environments for a test to run. After a long time, it seems that we are against the original intention of the test. This not only consumes time, but also introduces a lot of coupling factors to the test process. For example, someone may be eager to change an interface or a table in the database. Suddenly, your humble unit test is mysterious. After this happens several times, even the most patient developer will be discouraged, and even eventually give up all the tests, then the consequences will be unimaginable.
Let's look at a more specific situation: in the actual object-oriented software design, we often encounter such a situation. After we build a realistic object, objects are implemented through a series of interfaces. This is the most natural thing in object-oriented design, but with the development of software testing requirements, this will produce some minor problems. For example, user A now obtains an interface provided by user B and implements his own needs based on this interface. However, after user A compiles his own code, he wants to simulate and test it, what should we do? This is also a very practical issue. Can we simply implement a proxy class for this interface to test the simulation and expect the code to generate its own results? Fortunately, there is a test mode that can help us: mock objects. The Mock object is a replacement of the real object during the debugging period.
When do I need to use Mock?
Tim macinnon gave us some suggestions on when to use the Mock object:
- Real objects have uncertain behaviors (produce unpredictable results, such as stock quotations)
- It is difficult to create real objects (such as specific web containers)
- Some actions of real objects are difficult to trigger (such as network errors)
- The program runs slowly due to actual conditions.
- Real objects have user interfaces
- The test needs to ask how the real object is called (for example, the test may need to verify whether a callback function is called)
- Real objects do not actually exist (this is a common problem when dealing with other development groups or new hardware systems)
How to Use Mock?
. NET Mock Framework, you can look at the following web pages:
- Comparison of. NET Mocking Framework
- What C # mocking framework to use?
- The Fakes Framework in Visual Studio 2012
There are two Mock Framework implementation methods: Dynamic proxy implementation and static weaving implementation at compile time. The usage of various frameworks will soon be mastered. The key is how to use various mock technologies. There are several main arguments:
- Frameworks such as Typemock, Moles, And The Fakes Framework can support Mock for Sealed Class, Non-Abstract Method, Non-Virtual Method, and Static Method. Some people think this is very powerful, and some people think it is not good. They think that frameworks like Moq and Rhino Mocks do not support mock in the above four situations, forcing the project to implement Dependency inversion reduces project coupling to achieve high testability and maintainability.
- When using the dynamic proxy Mock framework, the protected method must be virtual for "testability", because we need to override in the subclass. Similarly, the Mock framework must support virtual methods, even a public method. So, do you think this is a concession for testability? In other words, do you think that a protected method that cannot override will affect the functions of other public interfaces? Is this a reasonable design? If this is a reasonable design and you do not want to make such concessions ...... What should we do? (This section is taken from Lao Zhao's "unit test method related to protected members ")
- When using the dynamic proxy Mock framework, to test some Non-Abstract Method, Non-Virtual Method, and Static Method, a Wrapper of the tested Method/class is provided, is it appropriate to encapsulate calls that cannot directly access methods? Reference:
Http://blog.zhaojie.me/2009/08/unit-test-protected-method.html#comment_iX2whQ8q04I003i2
Http://blog.zhaojie.me/2009/08/unit-test-protected-method.html#comment_iX2whQ8q04I003hi
Refer:
- Brief Introduction to Mock
- Use Mono. Cecil to solve non-virtual Mock methods and closed classes
- Unit test methods related to protected members
- How do I Mock non-Virtual Methods and sealing classes?
- Know when to use Override and New keywords (C # programming guide)
- C # class tutorial-Polymorphism