c# itextsharp pdfreader not opened with owner password : Delete pdf pages in reader SDK Library API wpf .net asp.net sharepoint The%20Art%20of%20Unit%20Testing%20with%20Examples%20in%20.NET%20(Manning%202009)18-part1049

Building a test API for your application
155
We could refactor the test classes and create a base test class that con-
tains the setup method. The full code for the test classes is shown in 
listing 6.2.
Listing 6.2  A refactored solution
public class BaseTestClass
{
[SetUp]
public void Setup()         
           
Console.WriteLine("in setup");
LoggingFacility.Logger = new StubLogger();
     
}
[TestFixture]
public class LogAnalyzerTests : BaseTestClass |#2
{
[Test]
public void Analyze_EmptyFile_ThrowsException()
{
LogAnalyzer la = new LogAnalyzer();
la.Analyze("myemptyfile.txt");
//rest of test
}
}
[TestFixture]
public class ConfigurationManagerTests :BaseTestClass
{
[Test]
public void Analyze_EmptyFile_ThrowsException()
{
ConfigurationManager cm = new ConfigurationManager();
bool configured = cm.IsConfigured("something");
//rest of test
}
}
Figure 6.3 shows this pattern more clearly.
Refactors into  
a common  
setup method
Inherits Setup() 
method  
implementation
Delete pdf pages in reader - remove PDF pages in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Provides Users with Mature Document Manipulating Function for Deleting PDF Pages
delete page pdf online; delete pdf page acrobat
Delete pdf pages in reader - VB.NET PDF Page Delete Library: remove PDF pages in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Visual Basic Sample Codes to Delete PDF Document Page in .NET
delete page in pdf document; copy pages from pdf to another pdf
156
CHAPTER 6    Test hierarchies and organization
The Setup method from the base class is now automatically run before 
each test in either of the derived classes. We’ve definitely reused some 
code, but there are pros and cons in every technique. The main prob-
lem we’ve introduced into the derived test classes is that anyone read-
ing the code can no longer easily understand what happens when setup 
is called. They will have to look up the setup method in the base class 
to see what the derived classes get by default. This leads to less read-
able tests, but it also leads to more code reuse.
What  if  you  wanted  to  have  your  own  derived  setup  in  one  of  the 
derived  classes?  Most  of  the  unit-testing  frameworks  (including 
NUnit) will allow you to make the setup method virtual and then over-
ride it in the derived class. Listing 6.3 shows how a derived class can 
have  its  own  setup method  but  still  keep  the  original  setup method 
(making them work one after the other).
Listing 6.3  A derived test class with its own setup method
public class BaseTestClass
{
[SetUp]
public virtual void Setup()|    
{
Figure 6.3 One base class with a common setup method, and two test classes that 
reuse that setup method
Makes Setup()  
virtual to allow  
overriding
C# PDF Page Insert Library: insert pages into PDF file in C#.net
how to merge PDF document files by C# code, how to rotate PDF document page, how to delete PDF page using C# .NET, how to reorganize PDF document pages and how
delete a page in a pdf file; delete page in pdf reader
C# PDF File & Page Process Library SDK for C#.net, ASP.NET, MVC
VB.NET Page: Insert PDF pages; VB.NET Page: Delete PDF pages; VB.NET Annotate: PDF Markup & Drawing. XDoc.Word for XImage.OCR for C#; XImage.Barcode Reader for C#
acrobat extract pages from pdf; delete pdf pages ipad
Building a test API for your application
157
Console.WriteLine("in setup");
LoggingFacility.Logger = new StubLogger();
}
}
[TestFixture]
public class ConfigurationManagerTests :BaseTestClass
{
[SetUp]
public override void Setup()   
{
base.Setup();
Console.WriteLine("in derived");
LoggingFacility.Logger = new StubLogger();
}
//...
}
This  style  of  inheritance  is  easier  for  the  reader  of  the  test  class, 
because it specifically indicates that there’s a base setup method that’s 
called each time. You may be helping your team by requiring them to 
always override base methods and call their base class’s implementa-
tion in the tests for the sake of readability. This approach is shown in 
listing 6.4.
Listing 6.4  Overriding a setup method purely for clarity
[TestFixture]
public class ConfigurationManagerTests :BaseTestClass
{
[SetUp]
public override void Setup()
{
base.Setup();         
}
//...
}
This type of coding may feel a bit weird at first, but anyone reading the 
tests will thank you for making it clear what’s going on.
Overrides and  
calls base 
Overrides and 
calls base
VB.NET PDF Page Insert Library: insert pages into PDF file in vb.
Page: Insert PDF Pages. |. Home ›› XDoc.PDF ›› VB.NET PDF: Insert PDF Page. Add and Insert Multiple PDF Pages to PDF Document Using VB.
add remove pages from pdf; delete page from pdf document
VB.NET PDF Page Extract Library: copy, paste, cut PDF pages in vb.
Page: Extract, Copy, Paste PDF Pages. |. Home ›› XDoc.PDF ›› VB.NET PDF: Copy and Paste PDF Page. VB.NET PDF - PDF File Pages Extraction Guide.
delete a page from a pdf acrobat; delete blank pages in pdf online
158
CHAPTER 6    Test hierarchies and organization
Template test class pattern
The 
template  test  class  pattern
creates  an  abstract  class  that  contains 
abstract test methods that derived classes will have to implement. The 
driving force  behind this pattern  is the need  to be able to dictate to 
deriving classes which tests they should always implement. It’s com-
monly used when there’s a need to create one or more test classes for a 
set of classes that implement the same interface. 
Think  of  an  interface  as  a “behavior  contract”  where  the  same  end 
behavior  is  expected  from  all  who  have  the  contract,  but  they  can 
achieve the end result in different ways. An example of such a behavior 
contract could be a set of parsers all implementing parse methods that 
act the same way but on different input types.
Developers often neglect or forget to write all the required tests for a 
specific case. Having a base class for each set of identically interfaced 
classes  can help  create a basic test  contract that  all developers must 
implement in derived test classes.
Figure 6.4 A template test pattern ensures 
that developers don’t forget important 
tests. The base class contains abstract 
tests that derived classes must implement.
C# PDF Page Extract Library: copy, paste, cut PDF pages in C#.net
C#.NET PDF Library - Copy and Paste PDF Pages in C#.NET. Easy to C#.NET Sample Code: Copy and Paste PDF Pages Using C#.NET. C# programming
add and delete pages from pdf; delete page from pdf reader
C# PDF Page Rotate Library: rotate PDF page permanently in C#.net
batch changing PDF page orientation without other PDF reader control. NET, add new PDF page, delete certain PDF page, reorder existing PDF pages and split
delete pages on pdf online; copy page from pdf
Building a test API for your application
159
Figure 6.4 shows an  example base class  that helps to test data-layer 
CRUD (create, retrieve, update, and delete ) classes.
I’ve found this technique useful in many situations, not only as a devel-
oper, but also as an architect. As an architect, I was able to supply a list 
of  essential test classes for  developers  to implement,  and  to provide 
guidance on what kinds of tests they’d want to write next. It’s essential 
in this situation that the naming of the tests is understandable.
But what if you were to inherit real tests from the base class, and not 
abstract ones?
Abstract test driver class pattern
The 
abstract test driver class pattern
creates an abstract test class that con-
tains  test  method  implementations that all derived classes inherit  by 
default,  without  needing  to  reimplement  them.  Instead  of  having 
abstract test methods, you  implement real tests on the abstract class 
that your derived classes will inherit. It’s essential that your tests don’t 
explicitly test  one  class type, but instead test against  an interface or 
base class in your production code under test. 
Let’s see a real scenario. Suppose you have the object model shown in 
figure 6.5 to test.
The 
BaseStringParser
is an abstract class that other classes derive from 
to  implement some  functionality  over  different  string  content  types. 
From each string type (XML strings, IIS log strings, standard strings), 
we can get some sort of versioning info (metadata on the string that 
was  put  there  earlier).  We  can  get  the  version  info  from  a  custom 
header (the first few lines of the string) and check whether that header 
is valid for the purposes of our application. The 
XMLStringParser
IIS-
LogStringParser
, and
StandardStringParser 
classes derive from this 
base  class  and  implement  the  methods  with  logic  for  their  specific 
string types.
The first step in testing such a hierarchy is to write a set of tests for one 
of the derived classes (assuming the abstract class has no logic to test in 
it).  Then  you’d  have  to  write  the  same  kinds  of  tests  for  the  other 
classes that have the same functionality.
C# Imaging - Scan Barcode Image in C#.NET
RasterEdge Barcode Reader DLL add-in enables developers to add barcode image recognition & barcode types, such as Code 128, EAN-13, QR Code, PDF-417, etc.
delete pdf pages android; delete pages in pdf
VB.NET PDF delete text library: delete, remove text from PDF file
Visual Studio .NET application. Delete text from PDF file in preview without adobe PDF reader component installed. Able to pull text
delete pages from a pdf document; delete blank page in pdf
160
CHAPTER 6    Test hierarchies and organization
Figure 6.5 A typical inheritance hierarchy that we’d like to test includes an abstract 
class and classes that derive from it.
Listing  6.5  shows  tests  for  the 
StandardStringParser
that  we  might 
start out with before we refactor our test classes.
Listing 6.5  An outline of a test class for StandardStringParser
[TestFixture]
public class StandardStringParserTests
{
private StandardStringParser GetParser(string input)
{
return new StandardStringParser(input);
}
[Test]
public void GetStringVersionFromHeader_SingleDigit_Found()
{
string input = "header;version=1;\n";
StandardStringParser parser = GetParser(input);
string versionFromHeader = parser.GetTextVersionFromHeader();
Assert.AreEqual("1",versionFromHeader);
}
Defines  
the parser 
factory 
method
?
Uses  
factory  
method
w
Building a test API for your application
161
[Test]
public void GetStringVersionFromHeader_WithMinorVersion_Found()
{
string input = "header;version=1.1;\n";
StandardStringParser parser = GetParser(input);
//rest of the test
}
[Test]
public void GetStringVersionFromHeader_WithRevision_Found()
{
string input = "header;version=1.1.1;\n";
StandardStringParser parser = GetParser(input);
//rest of the test
}
[Test]
public void HasCorrectHeader_NoSpaces_ReturnsTrue()
{
string input = "header;version=1.1.1;\n";
StandardStringParser parser = GetParser(input);
bool result = parser.HasCorrectHeader();
Assert.IsTrue(result);
}
[Test]
public void HasCorrectHeader_WithSpaces_ReturnsTrue()
{
string input = "header ; version=1.1.1 ; \n";
StandardStringParser parser = GetParser(input);
//rest of the test
}
[Test]
public void HasCorrectHeader_MissingVersion_ReturnsFalse()
{
string input = "header; \n";
StandardStringParser parser = GetParser(input);
//rest of the test
}
}
Uses  
factory  
method
w
162
CHAPTER 6    Test hierarchies and organization
Note how we use the 
GetParser()
helper method 
?
to refactor away 
w
the creation of the parser object, which we use in all the tests. We use 
the helper method, and not a setup method, because the constructor 
takes the input string to parse, so each test needs to be able to create a 
version of the parser to test with its own specific inputs.
When  you  start  writing  tests  for  the other  classes in  the  hierarchy, 
you’ll want to repeat the same tests that are in this specific parser class. 
All the other parsers should have the same outward behavior: getting 
the header version and validating that the header is valid. How they do 
this differs, but the behavior semantics are the same. This means that, 
for each class that derives from 
BaseStringParser
, we’d write the same 
basic tests, and only the type of class under test would change.
Instead of repeating all those tests manually, we can create a 
ParserT-
estsBase
class that contains all the basic tests we’d like to perform on 
any class that implements the 
IStringParser
interface (or any class that 
derives from 
BaseStringParser
). Listing 6.6 shows an example of this 
base class. 
Listing 6.6  An abstract test base class with test logic for IStringParser interface
public abstract class BaseStringParserTests
{
protected abstract IStringParser 
GetParser(string input);
[Test]
public void GetStringVersionFromHeader_SingleDigit_Found()
{
string input = "header;version=1;\n";
IStringParser parser = GetParser(input);
string versionFromHeader = parser.GetTextVersionFromHeader();
Assert.AreEqual("1",versionFromHeader);
}
[Test]
public void GetStringVersionFromHeader_WithMinorVersion_Found()
{
string input = "header;version=1.1;\n";
IStringParser parser = GetParser(input); 
//...
Turns GetParser() 
into an abstract method
?
Calls abstract  
factory method
w
Calls abstract  
factory method
w
Building a test API for your application
163
}
[Test]
public void GetStringVersionFromHeader_WithRevision_Found()
{
string input = "header;version=1.1.1;\n";
IStringParser parser = GetParser(input);
//...
}
[Test]
public void HasCorrectHeader_NoSpaces_ReturnsTrue()
{
string input = "header;version=1.1.1;\n";
IStringParser parser = GetParser(input);
bool result = parser.HasCorrectHeader();
Assert.IsTrue(result);
}
[Test]
public void HasCorrectHeader_WithSpaces_ReturnsTrue()
{
string input = "header ; version=1.1.1 ; \n";
IStringParser parser = GetParser(input);
//...
}
[Test]
public void HasCorrectHeader_MissingVersion_ReturnsFalse()
{
string input = "header; \n";
IStringParser parser = GetParser(input);
//...
}
}
Several things are different from listing 6.5 and are important in the 
implementation of the base class:
The 
GetParser()
method is abstract ?,  and its return type is now 
IStringParser
. This means we can override this factory method in 
derived test classes and return the type of the parser we’d like to test.
164
CHAPTER 6    Test hierarchies and organization
The test methods only get an 
IStringParser
interface 
w
and don’t 
know the actual class they’re running against.
A derived class can choose to add tests against a specific subclass of 
IStringParser
by adding another test method in its own test class (as 
we’ll see next).
Once we have the base class in order, we can easily add tests to the 
various subclasses. Listing 6.7 shows how we can write tests for the 
StandardStringParser
by deriving from 
BaseStringParserTests
.
Listing 6.7  A derived test class that overrides a small number of factory methods
[TestFixture]
public class StandardStringParserTests : BaseStringParserTests
{
protected override IStringParser GetParser(string input)
{
return new StandardStringParser(input);
}
[Test]
public void 
GetStringVersionFromHeader_DoubleDigit_Found()
{
//this test is specific to the StandardStringParser type
string input = "header;version=11;\n";
IStringParser parser = GetParser(input);
string versionFromHeader = parser.GetTextVersionFromHeader();
Assert.AreEqual("11", versionFromHeader);
}
}
Note that in listing 6.7 we only have two methods in the derived class:
The factory method ? that tells the base class what instance of the 
class to run tests on
A new test w that may not belong in the base class, or that may be 
specific to the current type under test
Overrides  
abstract factory
method
?
Adds  
new test
w
Documents you may be interested
Documents you may be interested