c# itextsharp pdfreader not opened with owner password : Add and delete pages from pdf application Library cloud windows asp.net wpf class The%20Art%20of%20Unit%20Testing%20with%20Examples%20in%20.NET%20(Manning%202009)23-part1055

Writing maintainable tests
205
return sb.ToString();
}
///TEST OUTPUT//////////////
------ Test started: Assembly: er.dll ------
TestCase 'AOUT.CH7.LogAn.Tests.MultipleAsserts
.Analyze_SimpleStringLine_UsesDefaulTabDelimiterToParseFields2'
failed:
Expected: <10:05,Open,Roy,>
But was:  <>
C:\GlobalShare\InSync\Book\Code\ARtOfUniTesting
\LogAn.Tests\MultipleAsserts.cs(41,0): 
at AOUT.CH7.LogAn.Tests.MultipleAsserts
.Analyze_SimpleStringLine_UsesDefaulTabDelimiterToParseFields2()
Now the test output is much clearer, and we can understand that we 
got very different objects. Clearer output makes it easier to understand 
why the test fails and makes for easier maintenance.
Another way tests can become hard to maintain is when we make them 
too fragile by overspecification.
7.2.7 Avoiding overspecification in tests
An overspecified test is one that contains assumptions about how a spe-
cific  unit  under  test  should  implement  its  behavior,  instead  of  only 
checking that the end behavior is correct. 
Here are some ways unit tests are often overspecified:
A test specifies purely internal behavior for an object under test.
A test uses mocks when using stubs would be enough.
A test assumes specific order or exact string matches when it isn’t 
required.
TIP
This topic is also discussed in 
xUnit Test Patterns
by Gerard Meszaros.
Let’s look at some examples of overspecified tests.
Specifying purely internal behavior
Listing  7.20 shows a test  against 
LogAnalyzer
’s 
Initialize()
method 
that tests internal state, and no outside functionality.
Add and delete pages from pdf - remove PDF pages in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Provides Users with Mature Document Manipulating Function for Deleting PDF Pages
delete blank pages in pdf; delete pages from a pdf document
Add and delete pages from pdf - 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
cut pages from pdf file; acrobat export pages from pdf
206
CHAPTER 7    The pillars of good tests
Listing 7.20  An overspecified test that tests a purely internal behavior
[Test]
public void Initialize_WhenCalled_SetsDefaultDelimiterIsTabDelimiter()
{
LogAnalyzer log = new LogAnalyzer();
Assert.AreEqual(null,log.GetInternalDefaultDelimiter());
log.Initialize();
Assert.AreEqual('\t', log.GetInternalDefaultDelimiter());
}
This  test  is  overspecified  because  it  only  tests  the  internal  state  of 
the 
LogAnalyzer
object. Because this state is internal, it could change 
later on. 
Unit tests should be testing the public contract and public functionality
of an object. In this example, the tested code isn’t part of any public 
contract or interface.
Using mocks instead of stubs
Using mocks instead of stubs is a common mistake. Let’s look at an 
example.
Listing  7.21  shows  a  test  that  uses  mocks  to  assert  the  interaction 
between 
LogAnalyzer
and a provider it uses to read a text file. The test 
wrongly checks that 
LogAnalyzer
calls the provider correctly to  read 
the file’s text (an implementation  detail  that could change  later and 
break our test). Instead, the test could use a stub to return the fake 
results from the text file, and assert against the public output of the 
LogAnalyzer
’s method, which makes for a more robust, less brittle test.
Listing 7.21 shows the method we want to test, followed by an over-
specified test for that code.
Listing 7.21  An overspecified test that uses mocks when stubs would do fine
public AnalyzeResults AnalyzeFile(string fileName)
{
int lineCount = logReader.GetLineCount();
string text = "";
C# PDF File & Page Process Library SDK for C#.net, ASP.NET, MVC
C# Page: Insert PDF pages; C# Page: Delete PDF pages; C# Read: PDF Text Extract; C# Read: PDF Image Extract; C# Write: Insert text into PDF; C# Write: Add Image
delete pages from pdf preview; delete blank pages in pdf online
C# PDF Page Insert Library: insert pages into PDF file in C#.net
processing control SDK, you can create & add new PDF rotate PDF document page, how to delete PDF page using NET, how to reorganize PDF document pages and how
delete a page from a pdf file; add remove pages from pdf
Writing maintainable tests
207
for (int i = 0; i < lineCount; i++)
{
text += logReader.GetText(fileName, i, i);
}
return new AnalyzeResults(text);
}
//////////////////////////the test/////////////////
[Test]
public void AnalyzeFile_FileWith3Lines_CallsLogProvider3Times()
{
MockRepository mocks = new MockRepository();
ILogProvider mockLog = mocks.CreateMock<ILogProvider>();
LogAnalyzer log = new LogAnalyzer(mockLog);
using(mocks.Record())
{
mockLog.GetLineCount();
LastCall.Return(3);
mockLog.GetText("someFile.txt", 1, 1);
LastCall.Return("a");
mockLog.GetText("someFile.txt", 2, 2);
LastCall.Return("b");
mockLog.GetText("someFile.txt", 3, 3);
LastCall.Return("c");
}
AnalyzeResults results = log.AnalyzeFile("someFile.txt");
mocks.VerifyAll();
}
The test in listing 7.21 is overspecified because it tests the interaction 
between the interface of some 
LogReader
(which reads text files) and 
the 
LogAnalzyer
object. This means it’s testing the underlying reading 
algorithm  inside  the  method  under  test,  instead  of  testing  for  an 
expected  result from  the  method under  test.  The  test  should let the 
method under test run its own internal algorithms, and test the results. 
By doing that, we make the test less brittle.
Listing 7.22 shows a modified test that only checks the outcome of the 
operation.
C# PDF insert image Library: insert images into PDF in C#.net, ASP
C#.NET PDF SDK - Add Image to PDF Page in C#.NET. How to Insert & Add Image, Picture or Logo on PDF Page Using C#.NET. Add Image to PDF Page Using C#.NET.
delete pdf pages; delete pages on pdf
VB.NET PDF Password Library: add, remove, edit PDF file password
passwordSetting.IsAssemble = True ' Add password to PDF file. These two demos will help you to delete password for an encrypted PDF file.
delete page from pdf acrobat; delete pages pdf files
208
CHAPTER 7    The pillars of good tests
Listing 7.22  Replacing mocks with stubs and checking outputs instead of interactions
[Test]
public void 
AnalyzeFile_With3Lines_CallsLog3TimesLessBrittle()
{
MockRepository mocks = new MockRepository();
ILogProvider stubLog = mocks.Stub<ILogProvider>();
using(mocks.Record())
{
SetupResult.For(stubLog.GetText("", 1, 1))
.IgnoreArguments()
.Repeat.Any()  
.Return("a");
SetupResult.For(stubLog.GetLineCount()).Return(3);
}
using(mocks.Playback())
{
LogAnalyzer log = new LogAnalyzer(stubLog);
AnalyzeResults results = log.AnalyzeFile("someFile.txt");
Assert.That(results.Text,Is.EqualTo("aaa"));
}
}
The important thing about this test is that the end assert ? is against 
the end result, and it doesn’t care how many times the internal 
Get-
Text()
method is called. We also use a stub that doesn’t care how many 
times it gets called, and it always returns the same result. This test is 
much less fragile, and it tests the right thing.
NOTE
When  you  refactor  internal  state  to  be  visible  to  an  outside  test, 
could it be considered a code smell (a sign that something might be 
wrong  in  the code’s design  or  logic)?  It’s  not  a  code  smell  when 
you’re refactoring to expose collaborators. It’s a code smell if you’re 
refactoring and there are no collaborators (so you don’t need to stub 
or mock anything).
I  am  using  NUnit’s 
Assert.That
syntax  instead  of 
Assert.AreEqual
because the fluent nature of the new syntax is much cleaner and nicer 
to work with.
Stubs unknown  
number of calls
Asserts on  
end result
?
VB.NET PDF Page Insert Library: insert pages into PDF file in vb.
Able to add and insert one or multiple pages to existing adobe PDF document in VB.NET. Add and Insert Multiple PDF Pages to PDF Document Using VB.
acrobat extract pages from pdf; delete page on pdf document
C# PDF Sticky Note Library: add, delete, update PDF note in C#.net
C#.NET PDF SDK - Add Sticky Note to PDF Page in C#.NET. Able to add notes to PDF using C# source code in Visual Studio .NET framework.
delete pages from pdf without acrobat; add and remove pages from pdf file online
Writing readable tests
209
TIP
Also notice that this test has no mock objects, only stubs. The assert is 
done against a  return value, and  a stub is used internally to  simulate 
some scenario. This is often the way I like to write my tests. In fact, less 
than 10 percent of the tests I write have any mock objects. Most tests 
will have stubs, and nothing more.
One more way developers tend to overspecify their tests is the overuse 
of assumptions.
Assuming an order or exact match when it’s not needed
Another  common  pattern  people  tend  to  repeat  is  to  have  asserts 
against hardcoded strings in the unit’s return value or properties, when 
only a specific part of a string is necessary. Ask yourself, “Can I use 
string.Contains()
rather than 
string.Equals()
?” 
The same goes for collections and lists. It’s much better to make sure a 
collection contains an expected item than to assert that the item is in a 
specific place in a collection (unless that’s specifically what is expected). 
By making these kinds of small adjustments, you can guarantee that, as 
long as the string or collection contains what is expected, the test will 
pass.  Even  if the implementation or order  of the string or collection 
changes, you won’t have to go back and change every little character 
you add to a string.
Now let’s cover the third and final pillar of good unit tests: readability. 
Readability  is  so  important  that,  without  it,  the  tests  we  write  are 
almost  meaningless.  From giving  good  names  to  the  tests to having 
good assert messages, readability is the connecting thread between the 
person who wrote the test and the poor soul who has to read it a few 
months later. Tests are stories we tell the next generation of program-
mers on a project. They allow a developer to see exactly what an appli-
cation is made of and where it started.
This section is all about making sure the developers who come after 
you will be able to maintain the production code and the tests that you 
7.3 Writing readable tests
VB.NET PDF insert image library: insert images into PDF in vb.net
with this sample VB.NET code to add an image to textMgr.SelectChar(page, cursor) ' Delete a selected As String = Program.RootPath + "\\" output.pdf" doc.Save
delete pages on pdf online; delete page in pdf online
C# PDF Password Library: add, remove, edit PDF file password in C#
passwordSetting.IsAssemble = true; // Add password to PDF file. These C# demos will help you to delete password for an encrypted PDF file.
delete page pdf file; copy pages from pdf to word
210
CHAPTER 7    The pillars of good tests
write, while understanding what they’re doing and where they should 
be doing it.
There are several facets to readability:
Naming unit tests
Naming variables
Creating good assert messages
Separating asserts from actions
Let’s go through these one by one.
7.3.1 Naming unit tests
Naming  standards  are  important  because  they  give  us  comfortable 
rules and templates that outline what we should explain about the test. 
The test name has three parts:
The name of the method being tested—
This is essential, so that you can easily 
see where the tested logic is. Having this as the first part of the test 
name allows easy navigation and as-you-type intellisense (if your IDE 
supports it) in the test class.
The scenario under which it’s being tested—
This part gives us the “with” part of 
the name: “When I call method X 
with a null value
, then it should do Y.”
The  expected  behavior  when  the  scenario  is  invoked—
This  part  specifies  in 
plain English what the method should do or return, or how it should 
behave, based on the current scenario: “When I call method X with a 
null value, 
then it should do Y
.”
Removing even one of these parts from a test name can cause the reader 
of the test to wonder what is going on, and to start reading the test code. 
Our main goal is to release the next developer from the burden of read-
ing the test code in order to understand what the test is testing.
A common way to write these three parts of the test name is to separate 
them with underscores, like this: 
MethodUnderTest_Scenario_Behavior()
Listing 7.23 shows a test that uses this naming convention.
Writing readable tests
211
Listing 7.23  A test with three parts in its name
[Test]
public void
AnalyzeFile_FileWith3LinesAndFileProvider_ReadsFileUsingProvider()
{
//...
}
The method in listing 7.23 tests the 
AnalyzeFile
method, giving it a file 
with three lines and a file-reading provider, and expects it to use the 
provider to read the file.
If developers stick to this naming convention, it will be easy for other 
developers to jump in and understand tests.
7.3.2 Naming variables
How you name variables in unit tests is as important as, or even more 
important  than,  variable-naming  conventions  in  production  code. 
Apart from their chief function of testing, tests also serve as a form of 
documentation for an  API.  By giving variables  good  names,  we can 
make sure that people reading our tests understand what we’re trying 
to 
prove
as quickly as possible (as opposed to understanding what we’re 
trying to 
accomplish
when writing production code).
Listing 7.24 shows an example of a poorly named and poorly written 
test. I call this “unreadable” in the sense that I can’t figure out what this 
test is about. 
Listing 7.24  An unreadable test name
[Test]
public void BadlyNamedTest()
{
LogAnalyzer log = new LogAnalyzer();
int result= log.GetLineCount("abc.txt");
Assert.AreEqual(-100,result);
}
212
CHAPTER 7    The pillars of good tests
In this instance, the assert is using some magic number (-100) (a num-
ber that represents some value the developer needs to know). Because 
we don’t have a descriptive name for what the number is expected to 
be,  we  can  only 
assume
what  it’s  supposed  to  mean.  The  test  name 
should have helped us a little bit here, but the test name needs more 
work, to put it mildly.
Is -100 some sort of exception? Is it a valid return value? This is where 
we have a choice:
We can change the design of the API to throw an exception instead 
of returning -100 (assuming -100 is some sort of illegal result value).
We can compare the result to some sort of constant or aptly named 
variable, as shown in listing 7.25.
Listing 7.25  A more readable version of the test
[Test]
public void BadlyNamedTest()
{
LogAnalyzer log = new LogAnalyzer();
int result= log.GetLineCount("abc.txt");
const int COULD_NOT_READ_FILE = -100;
Assert.AreEqual(COULD_NOT_READ_FILE,result);
}
The code in listing 7.25 is much better, because we can easily under-
stand the intent of the return value.
The last part of a test is usually the assert, and we need to make the 
most out of the assert message. If the assert fails, the first thing the user 
will see is that message. 
7.3.3 Asserting yourself with meaning
Writing a good assert message is much like writing a good exception 
message. It’s easy to get it wrong without realizing it, and it makes a 
world of difference (and time) to the people who have to read it.
There are several key points to remember when writing a message for 
an assert clause:
Writing readable tests
213
Don’t repeat what the built-in test framework outputs to the console.
Don’t repeat what the test name explains.
If you don’t have anything good to say, don’t say anything.
Write  what  should have  happened or what  failed  to  happen, and 
possibly mention when it should have happened.
Listing 7.26 shows a bad example of an assert message and the output 
it produces.
Listing 7.26  A bad assert message that repeats what the test framework outputs
[Test]
public void BadAssertMessage()
{
LogAnalyzer log = new LogAnalyzer();
int result= log.GetLineCount("abc.txt");
const int COULD_NOT_READ_FILE = -100;
Assert.AreEqual(COULD_NOT_READ_FILE,result,
"result was {0} instead of {1}",
result,COULD_NOT_READ_FILE);
}
//Running this would produce:
TestCase 'AOUT.CH7.LogAn.Tests.Readable.BadAssertMessage'
failed:
result was -1 instead of -100
Expected: -100
But was:  -1
C:\GlobalShare\InSync\Book\Code
\ARtOfUniTesting\LogAn.Tests\Readable.cs(23,0)
: at AOUT.CH7.LogAn.Tests.Readable.BadAssertMessage()
As  you  can see,  there’s  a  message that  repeats.  Our  assert message 
didn’t  add anything except more words to read. It would have been 
better to not output anything but instead have a better-named test. A 
clearer assert message would be something like this: 
Calling GetLineCount() for a non-existing file should have returned 
a COULD_NOT_READ_FILE.
Now that your assert messages are understandable, it’s time to make 
sure that the assert happens on a different line than the method call. 
214
CHAPTER 7    The pillars of good tests
7.3.4 Separating asserts from actions
This is a short section, but an important one nonetheless. For the sake 
of readability, avoid writing the assert line and the method call in the 
same statement. 
Listing 7.27 shows a good example, and listing 7.28 shows a bad example.
Listing 7.27  Separating the assert from the thing asserted improves readability
[Test]
public void BadAssertMessage()
{
//some code here
int result= log.GetLineCount("abc.txt");
Assert.AreEqual(COULD_NOT_READ_FILE,result);
}
Listing 7.28  Not separating the assert from the thing asserted makes reading difficult
[Test]
public void BadAssertMessage()
{
//some code here
Assert.AreEqual(COULD_NOT_READ_FILE,log.GetLineCount("abc.txt"));
}
See the  difference between  the two  examples?  Listing  7.28 is much 
harder to read and understand in the context of a real test, because the 
call to the 
GetLineCount()
method is inside the call to the assert message.
7.3.5 Setting up and tearing down
Setup and teardown methods in unit tests can be abused to the point 
where the tests  or the setup and teardown  methods are unreadable. 
Usually the situation is worse in the setup method than the teardown 
method.
Let’s look at one possible abuse. If you have mocks and stubs being set 
up in a setup method, that means they don’t get set up in the actual test. 
That, in turn, means that whoever is reading your test may not even 
Documents you may be interested
Documents you may be interested