<feed xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns="http://www.w3.org/2005/Atom" xml:lang="de-CH">
    <title>nettigkeiten.ch</title>
    <link rel="self" type="application/xml" href="http://blog.nettigkeiten.ch/Atom.aspx" />
    <subtitle type="html" />
    <id>http://blog.nettigkeiten.ch/Default.aspx</id>
    <author>
        <name>Dani</name>
        <uri>http://blog.nettigkeiten.ch/Default.aspx</uri>
    </author>
    <generator uri="http://subtextproject.com" version="Subtext Version 1.9.5.177">Subtext</generator>
    <updated>2008-10-02T20:49:02Z</updated>
    <entry>
        <title>Mehrspaltige DropDownList / ListBox</title>
        <link rel="self" type="text/html" href="http://blog.nettigkeiten.ch/archive/2008/10/02/mehrspaltige-dropdownlist--listbox.aspx" />
        <id>http://blog.nettigkeiten.ch/archive/2008/10/02/mehrspaltige-dropdownlist--listbox.aspx</id>
        <published>2008-10-02T20:49:0202:00:00</published>
        <updated>2008-10-02T20:49:02Z</updated>
        <content type="html">&lt;p&gt;Eine doch lästige und unschöne Einschränkung bei der DropDownList ist doch, dass man nur ein Feld der DataSource an das Control binden kann. &lt;/p&gt;  &lt;p&gt;Oft will man halt aber mehr als nur ein Feld darstellen:&lt;/p&gt;  &lt;p&gt;Kategorie A: 3 Fahrzeuge&lt;/p&gt;  &lt;p&gt;Kategorie B: 11 Fahrzeuge&lt;/p&gt;  &lt;p&gt;Kategorie C: 1 Fahrzeug&lt;/p&gt;  &lt;p&gt;Natürlich geht das relativ problemlos, z.B. mittels String-Concatenation, ist aber doch lästig, wenn man sonst alles schön über direktes DataBinding lösen könnte – zumal das Control ja auch einen FormatString zur Steuerung der Ausgabe entgegennimmt.&lt;/p&gt;  &lt;p&gt;Eine Ableitung der DropDownList zu bauen, die das kann, ist zum Glück keine Kunst. Nachfolgend das Beispiel mit einer DropDown-List, die ListBox verhält sich analog.&lt;/p&gt;  &lt;p&gt;Zuerst erstellt man sich also eine Klasse, die von DropDownList erbt:&lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;   &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MultiColumnDropDownList : DropDownList&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Die DropDownList nimmt den Namen des anzuzeigenden DataSource-Feldes im Property DataTextField auf. Ich benutze das Property gleich auch für meine Zwecke, lasse aber mehrere Angaben, getrennt durch ein Semikolon zu.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Die einzige Methode dies es dann zu überschreiben gilt ist PerformDataBinding. Dort kriegt man als Parameter die DataSource praktisch als IEnumerable.&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; PerformDataBinding(System.Collections.IEnumerable dataSource)&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Die eigentliche Implementation ist dann denkbar simpel: &lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (Object obj &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dataSource)&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] textFieldsValues = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[textFields.Length];&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; textFields.Length; i++)&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     {&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;         textFieldsValues[i] = DataBinder.GetPropertyValue(obj, textFields[i].Trim()).ToString();&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;     }&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;     ListItem li = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ListItem();&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;     li.Text = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(list.DataTextFormatString, textFieldsValues);&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;     li.Value = DataBinder.GetPropertyValue(obj, list.DataValueField);&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;     list.Items.Add(li);&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In Zeile 6 wird mittels der DataBinder-Klasse der Wert aus der DataSource gelesen. Hat den Vorteil, dass man sich nicht darum kümmern muss, was denn nun für eine DataSource dahinter steckt. Der Rest ist wohl selbsterklärend.&lt;/p&gt;

&lt;p&gt;Eingebunden in einer aspx-Seite sieht dann das so aus:&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &amp;lt;NN:MultiColumnDropDownList  ID=&lt;span style="color: #006080"&gt;"ddlMulti"&lt;/span&gt; runat=&lt;span style="color: #006080"&gt;"server"&lt;/span&gt; &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;             DataSourceID=&lt;span style="color: #006080"&gt;"ObjectDataSource1"&lt;/span&gt; DataTextField=&lt;span style="color: #006080"&gt;"Name;PreName"&lt;/span&gt; &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;             DataValueField=&lt;span style="color: #006080"&gt;"Id"&lt;/span&gt; DataTextFormatString=&lt;span style="color: #006080"&gt;"{0} {1}"&lt;/span&gt; /&amp;gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Und als Ausgabe:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.nettigkeiten.ch/images/blog_nettigkeiten_ch/WindowsLiveWriter/MultiColumnDropDownList_13B0F/greenshot_2008-10-02_20-38-46_2.jpg" rel="lightbox"&gt;&lt;img title="greenshot_2008-10-02_20-38-46" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="68" alt="greenshot_2008-10-02_20-38-46" src="http://blog.nettigkeiten.ch/images/blog_nettigkeiten_ch/WindowsLiveWriter/MultiColumnDropDownList_13B0F/greenshot_2008-10-02_20-38-46_thumb.jpg" width="115" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.nettigkeiten.ch/Files/MultiColumnList.zip"&gt;Download&lt;/a&gt; der Sourcen&lt;/p&gt;&lt;img src="http://blog.nettigkeiten.ch/aggbug/219.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://blog.nettigkeiten.ch/comments/219.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.nettigkeiten.ch/comments/commentRss/219.aspx</wfw:commentRss>
        <trackback:ping>http://blog.nettigkeiten.ch/services/trackbacks/219.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Herrlich! G&amp;ouml;ttlich!</title>
        <link rel="self" type="text/html" href="http://blog.nettigkeiten.ch/archive/2008/10/02/herrlich-goumlttlich.aspx" />
        <id>http://blog.nettigkeiten.ch/archive/2008/10/02/herrlich-goumlttlich.aspx</id>
        <published>2008-10-02T18:29:2802:00:00</published>
        <updated>2008-10-02T18:29:28Z</updated>
        <content type="html">&lt;p&gt;Leider hört man ja von Maradona eigentlich selten noch erfreuliches, das soll aber nicht daran hindern, sich an alten Perlen zu erfreuen. Auf so eine bin ich heute im &lt;a href="http://www.blick.ch/sport/fussball/saeugling-unterschreibt-bei-atletico-madrid-101807"&gt;Schweizer Schundblatt Nr. 1&lt;/a&gt; gestossen:&lt;/p&gt;  &lt;p&gt;   &lt;/p&gt;&lt;div class="wlWriterEditableSmartContent" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:cd882bb1-bd8d-407c-9adb-57e2ffaa2523" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;div id="1c5bcd3d-6154-4176-8fec-06260bce1b05" style="margin: 0px; padding: 0px; display: inline;"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=bbaa2oTazMU" target="_new"&gt;&lt;img src="http://blog.nettigkeiten.ch/images/blog_nettigkeiten_ch/WindowsLiveWriter/HerrlichGttlich_10404/video2628ec8552d3.jpg" style="border-style: none" galleryimg="no" onload="var downlevelDiv = document.getElementById('1c5bcd3d-6154-4176-8fec-06260bce1b05'); downlevelDiv.innerHTML = &amp;quot;&amp;lt;div&amp;gt;&amp;lt;object width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;param name=\&amp;quot;movie\&amp;quot; value=\&amp;quot;http://www.youtube.com/v/bbaa2oTazMU&amp;amp;hl=en\&amp;quot;&amp;gt;&amp;lt;\/param&amp;gt;&amp;lt;embed src=\&amp;quot;http://www.youtube.com/v/bbaa2oTazMU&amp;amp;hl=en\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;\/embed&amp;gt;&amp;lt;\/object&amp;gt;&amp;lt;\/div&amp;gt;&amp;quot;;" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;   &lt;p&gt;Da ist sogar das Einspielen ein Highlight!&lt;/p&gt;  &lt;p&gt;Perfekte Einstimmung für heute Abend, wenn der FC Zürich, zwar kaum so brilliant, aber hoffentlich mit viel Kämpferherz die Milanesi rauskickt. :-)&lt;/p&gt;&lt;img src="http://blog.nettigkeiten.ch/aggbug/218.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://blog.nettigkeiten.ch/comments/218.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.nettigkeiten.ch/comments/commentRss/218.aspx</wfw:commentRss>
        <trackback:ping>http://blog.nettigkeiten.ch/services/trackbacks/218.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Private Methoden mit UnitTests testen</title>
        <link rel="self" type="text/html" href="http://blog.nettigkeiten.ch/archive/2008/09/30/private-methoden-mit-unittests-testen.aspx" />
        <id>http://blog.nettigkeiten.ch/archive/2008/09/30/private-methoden-mit-unittests-testen.aspx</id>
        <published>2008-09-30T21:29:3402:00:00</published>
        <updated>2008-09-30T21:29:34Z</updated>
        <content type="html">&lt;p&gt;Das Testen von privaten Methoden wirft immer wieder Fragen auf. Natürlich gibt es hierfür auch diverse Lösungen:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Visual Studio erstellt einen sogenannten Private Accessor, was schlussendlich nichts anderes als ein Wrapper ist, der mittels Reflection auf die privaten Members zugreift.      &lt;br /&gt;Das ganze ist mir eher unsympathisch und verkompliziert das ganze nur. Ausserdem entstehen Schwierigkeiten beim Mocking. Trotzdem war dies bis jetzt die Lösung meiner Wahl.      &lt;br /&gt;&lt;a href="http://blog.nettigkeiten.ch/images/blog_nettigkeiten_ch/WindowsLiveWriter/PrivateMethodenmitUnitTeststesten_11972/TestReference_2.png" rel="lightbox"&gt;&lt;img title="TestReference" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="TestReference" src="http://blog.nettigkeiten.ch/images/blog_nettigkeiten_ch/WindowsLiveWriter/PrivateMethodenmitUnitTeststesten_11972/TestReference_thumb.png" width="207" border="0" /&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Private Members gar nicht testen. Da private Methoden in der Regel irgendwo mal aufgerufen werden, kann man diese über Tests von öffentlichen Methoden abhandeln. Mittels CodeCoverage lässt sich überwachen, dass die Methoden auch wirklich getestet werden. Nur wiederspricht das natürlich klar den Gesetzen von UnitTests. &lt;/li&gt;    &lt;li&gt;Natürlich kann man sich auch etwas eigenes bauen, um mittels Reflection an die Methoden zu kommen.      &lt;br /&gt;Neben dem Aufwand birgt das natürlich auch Fehlerpotential – und Fehler in Tests sind eher doof :-) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Alles also irgendwie ok – aber halt doch nicht so. Heute bin ich aber über zwei Klassen gestossen, mit denen man das Problem doch recht einfach lösen kann: &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.privateobject(VS.80).aspx"&gt;PrivateObject&lt;/a&gt; und &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.privatetype(VS.80).aspx"&gt;PrivateType&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Und so siehts aus:&lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;   &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; name = &lt;span style="color: #006080"&gt;"Dani"&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; expected = &lt;span style="color: #006080"&gt;"Hello Dani"&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;  &lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; MyClass mc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MyClass();&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; PrivateObject po = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PrivateObject(mc);&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; actual = po.Invoke(&lt;span style="color: #006080"&gt;"SayHello"&lt;/span&gt;, name).ToString();&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Und für statische Methoden nimmt man einfach PrivateType:&lt;/p&gt;

&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
  &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; PrivateType pt = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PrivateType(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(MyClass));&lt;/pre&gt;

    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; actual = pt.InvokeStatic(&lt;span style="color: #006080"&gt;"SayBye"&lt;/span&gt;, name).ToString();&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;img src="http://blog.nettigkeiten.ch/aggbug/217.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://blog.nettigkeiten.ch/comments/217.aspx</wfw:comment>
        <slash:comments>5</slash:comments>
        <wfw:commentRss>http://blog.nettigkeiten.ch/comments/commentRss/217.aspx</wfw:commentRss>
        <trackback:ping>http://blog.nettigkeiten.ch/services/trackbacks/217.aspx</trackback:ping>
    </entry>
    <entry>
        <title>nettigkeiten.ch goes Mobile!</title>
        <link rel="self" type="text/html" href="http://blog.nettigkeiten.ch/archive/2008/07/25/nettigkeiten.ch-goes-mobile.aspx" />
        <id>http://blog.nettigkeiten.ch/archive/2008/07/25/nettigkeiten.ch-goes-mobile.aspx</id>
        <published>2008-07-25T00:22:4202:00:00</published>
        <updated>2008-07-25T00:22:42Z</updated>
        <content type="html">&lt;p&gt;Dank der &lt;a href="http://feeds.beetagg.com"&gt;MobileFeeds&lt;/a&gt;-Applikation meines früheren Arbeitgebers &lt;a href="http://www.connvision.com"&gt;Connvision&lt;/a&gt; kann mein Blog nun auch komfortabel auf einem Mobile-Phone gelesen werden (mit entsprechend angepasster Darstellung).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://feeds.beetagg.com"&gt;&lt;img alt="mobilefeeds" src="http://blog.nettigkeiten.ch/images/blog_nettigkeiten_ch/WindowsLiveWriter/nettigkeiten.chgoesMobile_4DE/mobilefeeds_3.gif" width="240" height="68" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Als Leckerli erhält man bei MobileFeeds auch gleich einen &lt;a href="http://blog.nettigkeiten.ch/archive/2006/06/02/beetagg.aspx"&gt;BeeTagg&lt;/a&gt; der auf den Mobile-Feed linkt. Die Software die man benötigt, um den BeeTagg zu lesen kriegt man &lt;a href="http://get.beetagg.com"&gt;hier&lt;/a&gt; oder auch über Wap-Push (weitere Infos: &lt;a href="http://www.beetagg.com"&gt;beetagg.com&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;Ist der Reader erst installiert, kann man den untenstehenden BeeTagg lesen und wird auf den MobileFeed geleitet.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.nettigkeiten.ch/images/blog_nettigkeiten_ch/WindowsLiveWriter/nettigkeiten.chgoesMobile_4DE/beetagg.nettigkeiten_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" border="0" alt="beetagg.nettigkeiten" src="http://blog.nettigkeiten.ch/images/blog_nettigkeiten_ch/WindowsLiveWriter/nettigkeiten.chgoesMobile_4DE/beetagg.nettigkeiten_thumb.png" width="240" height="240" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Hier noch eine kleine Demo wie kinderleicht das mit dem BeeTagg scannen so funktioniert:&lt;/p&gt;  &lt;div style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px; display: inline" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:eefb529a-d235-466d-83e4-33bba0a733d9" class="wlWriterSmartContent"&gt;&lt;div id="7b874537-404b-416d-b771-238db6366123" style="margin: 0px; padding: 0px; display: inline;"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=JQ0k--XQzZY&amp;amp;hl=en&amp;amp;fs=1" target="_new"&gt;&lt;img src="http://blog.nettigkeiten.ch/images/blog_nettigkeiten_ch/WindowsLiveWriter/nettigkeiten.chgoesMobile_4DE/videoc98e00e2cf39.jpg" galleryimg="no" onload="var downlevelDiv = document.getElementById('7b874537-404b-416d-b771-238db6366123'); downlevelDiv.innerHTML = &amp;quot;&amp;lt;div&amp;gt;&amp;lt;object width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;param name=\&amp;quot;movie\&amp;quot; value=\&amp;quot;http://www.youtube.com/v/JQ0k--XQzZY&amp;amp;hl=en&amp;amp;fs=1\&amp;quot;&amp;gt;&amp;lt;\/param&amp;gt;&amp;lt;param name=\&amp;quot;wmode\&amp;quot; value=\&amp;quot;transparent\&amp;quot;&amp;gt;&amp;lt;\/param&amp;gt;&amp;lt;embed src=\&amp;quot;http://www.youtube.com/v/JQ0k--XQzZY&amp;amp;hl=en&amp;amp;fs=1\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; wmode=\&amp;quot;transparent\&amp;quot; width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;\/embed&amp;gt;&amp;lt;\/object&amp;gt;&amp;lt;\/div&amp;gt;&amp;quot;;" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://blog.nettigkeiten.ch/aggbug/216.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://blog.nettigkeiten.ch/comments/216.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.nettigkeiten.ch/comments/commentRss/216.aspx</wfw:commentRss>
        <trackback:ping>http://blog.nettigkeiten.ch/services/trackbacks/216.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Restaurant-Tip: Focacceria, St. Gallen (CH)</title>
        <link rel="self" type="text/html" href="http://blog.nettigkeiten.ch/archive/2008/07/22/restaurant-tip-focacceria-st.-gallen-ch.aspx" />
        <id>http://blog.nettigkeiten.ch/archive/2008/07/22/restaurant-tip-focacceria-st.-gallen-ch.aspx</id>
        <published>2008-07-22T21:22:2002:00:00</published>
        <updated>2008-07-22T21:22:20Z</updated>
        <content type="html">&lt;link href="file:///C:\Users\dani\AppData\Local\Temp\msohtmlclip1\01\clip_filelist.xml" rel="File-List" /&gt;
&lt;link href="file:///C:\Users\dani\AppData\Local\Temp\msohtmlclip1\01\clip_themedata.thmx" rel="themeData" /&gt;
&lt;link href="file:///C:\Users\dani\AppData\Local\Temp\msohtmlclip1\01\clip_colorschememapping.xml" rel="colorSchemeMapping" /&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;
&lt;w:WordDocument&gt;
&lt;w:View&gt;Normal&lt;/w:View&gt;
&lt;w:Zoom&gt;0&lt;/w:Zoom&gt;
&lt;w:TrackMoves /&gt;
&lt;w:TrackFormatting /&gt;
&lt;w:HyphenationZone&gt;21&lt;/w:HyphenationZone&gt;
&lt;w:PunctuationKerning /&gt;
&lt;w:ValidateAgainstSchemas /&gt;
&lt;w:SaveIfXMLInvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;
&lt;w:IgnoreMixedContent&gt;false&lt;/w:IgnoreMixedContent&gt;
&lt;w:AlwaysShowPlaceholderText&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;
&lt;w:DoNotPromoteQF /&gt;
&lt;w:LidThemeOther&gt;DE-CH&lt;/w:LidThemeOther&gt;
&lt;w:LidThemeAsian&gt;X-NONE&lt;/w:LidThemeAsian&gt;
&lt;w:LidThemeComplexScript&gt;X-NONE&lt;/w:LidThemeComplexScript&gt;
&lt;w:Compatibility&gt;
&lt;w:BreakWrappedTables /&gt;
&lt;w:SnapToGridInCell /&gt;
&lt;w:WrapTextWithPunct /&gt;
&lt;w:UseAsianBreakRules /&gt;
&lt;w:DontGrowAutofit /&gt;
&lt;w:SplitPgBreakAndParaMark /&gt;
&lt;w:DontVertAlignCellWithSp /&gt;
&lt;w:DontBreakConstrainedForcedTables /&gt;
&lt;w:DontVertAlignInTxbx /&gt;
&lt;w:Word11KerningPairs /&gt;
&lt;w:CachedColBalance /&gt;
&lt;/w:Compatibility&gt;
&lt;w:BrowserLevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;
&lt;m:mathPr&gt;
&lt;m:mathFont m:val="Cambria Math" /&gt;
&lt;m:brkBin m:val="before" /&gt;
&lt;m:brkBinSub m:val="&amp;#45;-" /&gt;
&lt;m:smallFrac m:val="off" /&gt;
&lt;m:dispDef /&gt;
&lt;m:lMargin m:val="0" /&gt;
&lt;m:rMargin m:val="0" /&gt;
&lt;m:defJc m:val="centerGroup" /&gt;
&lt;m:wrapIndent m:val="1440" /&gt;
&lt;m:intLim m:val="subSup" /&gt;
&lt;m:naryLim m:val="undOvr" /&gt;
&lt;/m:mathPr&gt;&lt;/w:WordDocument&gt;
&lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;
&lt;w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"
DefSemiHidden="true" DefQFormat="false" DefPriority="99"
LatentStyleCount="267"&gt;
&lt;w:LsdException Locked="false" Priority="0" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Normal" /&gt;
&lt;w:LsdException Locked="false" Priority="9" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="heading 1" /&gt;
&lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2" /&gt;
&lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3" /&gt;
&lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4" /&gt;
&lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5" /&gt;
&lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6" /&gt;
&lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7" /&gt;
&lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8" /&gt;
&lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9" /&gt;
&lt;w:LsdException Locked="false" Priority="39" Name="toc 1" /&gt;
&lt;w:LsdException Locked="false" Priority="39" Name="toc 2" /&gt;
&lt;w:LsdException Locked="false" Priority="39" Name="toc 3" /&gt;
&lt;w:LsdException Locked="false" Priority="39" Name="toc 4" /&gt;
&lt;w:LsdException Locked="false" Priority="39" Name="toc 5" /&gt;
&lt;w:LsdException Locked="false" Priority="39" Name="toc 6" /&gt;
&lt;w:LsdException Locked="false" Priority="39" Name="toc 7" /&gt;
&lt;w:LsdException Locked="false" Priority="39" Name="toc 8" /&gt;
&lt;w:LsdException Locked="false" Priority="39" Name="toc 9" /&gt;
&lt;w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption" /&gt;
&lt;w:LsdException Locked="false" Priority="10" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Title" /&gt;
&lt;w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font" /&gt;
&lt;w:LsdException Locked="false" Priority="11" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtitle" /&gt;
&lt;w:LsdException Locked="false" Priority="22" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Strong" /&gt;
&lt;w:LsdException Locked="false" Priority="20" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Emphasis" /&gt;
&lt;w:LsdException Locked="false" Priority="59" SemiHidden="false"
UnhideWhenUsed="false" Name="Table Grid" /&gt;
&lt;w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text" /&gt;
&lt;w:LsdException Locked="false" Priority="1" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="No Spacing" /&gt;
&lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading" /&gt;
&lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List" /&gt;
&lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid" /&gt;
&lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1" /&gt;
&lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2" /&gt;
&lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1" /&gt;
&lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2" /&gt;
&lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1" /&gt;
&lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2" /&gt;
&lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3" /&gt;
&lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List" /&gt;
&lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading" /&gt;
&lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List" /&gt;
&lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid" /&gt;
&lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 1" /&gt;
&lt;w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision" /&gt;
&lt;w:LsdException Locked="false" Priority="34" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="List Paragraph" /&gt;
&lt;w:LsdException Locked="false" Priority="29" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Quote" /&gt;
&lt;w:LsdException Locked="false" Priority="30" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Quote" /&gt;
&lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 1" /&gt;
&lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 2" /&gt;
&lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 3" /&gt;
&lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 4" /&gt;
&lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 5" /&gt;
&lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 6" /&gt;
&lt;w:LsdException Locked="false" Priority="19" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis" /&gt;
&lt;w:LsdException Locked="false" Priority="21" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis" /&gt;
&lt;w:LsdException Locked="false" Priority="31" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference" /&gt;
&lt;w:LsdException Locked="false" Priority="32" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Reference" /&gt;
&lt;w:LsdException Locked="false" Priority="33" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Book Title" /&gt;
&lt;w:LsdException Locked="false" Priority="37" Name="Bibliography" /&gt;
&lt;w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading" /&gt;
&lt;/w:LatentStyles&gt;
&lt;/xml&gt;&lt;![endif]--&gt;&lt;style type="text/css"&gt;&lt;!--
 /* Font Definitions */
 @font-face
	{font-family:"Cambria Math";
	panose-1:2 4 5 3 5 4 6 3 2 4;
	mso-font-charset:1;
	mso-generic-font-family:roman;
	mso-font-format:other;
	mso-font-pitch:variable;
	mso-font-signature:0 0 0 0 0 0;}
@font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;
	mso-font-charset:0;
	mso-generic-font-family:swiss;
	mso-font-pitch:variable;
	mso-font-signature:-1610611985 1073750139 0 0 159 0;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{mso-style-unhide:no;
	mso-style-qformat:yes;
	mso-style-parent:"";
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:10.0pt;
	margin-left:0cm;
	line-height:115%;
	mso-pagination:widow-orphan;
	font-size:11.0pt;
	font-family:"Calibri","sans-serif";
	mso-ascii-font-family:Calibri;
	mso-ascii-theme-font:minor-latin;
	mso-fareast-font-family:Calibri;
	mso-fareast-theme-font:minor-latin;
	mso-hansi-font-family:Calibri;
	mso-hansi-theme-font:minor-latin;
	mso-bidi-font-family:"Times New Roman";
	mso-bidi-theme-font:minor-bidi;
	mso-fareast-language:EN-US;}
.MsoChpDefault
	{mso-style-type:export-only;
	mso-default-props:yes;
	mso-ascii-font-family:Calibri;
	mso-ascii-theme-font:minor-latin;
	mso-fareast-font-family:Calibri;
	mso-fareast-theme-font:minor-latin;
	mso-hansi-font-family:Calibri;
	mso-hansi-theme-font:minor-latin;
	mso-bidi-font-family:"Times New Roman";
	mso-bidi-theme-font:minor-bidi;
	mso-fareast-language:EN-US;}
.MsoPapDefault
	{mso-style-type:export-only;
	margin-bottom:10.0pt;
	line-height:115%;}
@page Section1
	{size:595.3pt 841.9pt;
	margin:70.85pt 70.85pt 2.0cm 70.85pt;
	mso-header-margin:35.4pt;
	mso-footer-margin:35.4pt;
	mso-paper-source:0;}
div.Section1
	{page:Section1;}
--&gt;&lt;/style&gt;&lt;!--[if gte mso 10]&gt;
&lt;style&gt;
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin-top:0cm;
mso-para-margin-right:0cm;
mso-para-margin-bottom:10.0pt;
mso-para-margin-left:0cm;
line-height:115%;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;}
&lt;/style&gt;
&lt;![endif]--&gt;
&lt;p class="MsoNormal"&gt;Ein kleines Novum hier im Blog. Ab und an will ich in Zukunft auf, meiner Meinung nach, besonders erwähnenswerte Restaurants hinweisen. Ich verstehe dies auch als kleine Belohnung für die jeweilige Crew, welche sich abgemüht hat, meiner Begleitung und mir einen schönen Abend zu ermöglichen. Schliesslich gibt es ja leider genug andere Beispiele.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Wer die &lt;a href="http://www.focacceria.ch"&gt;Focacceria&lt;/a&gt; betritt, wird von einer warmen, etwas rustikalen und trotzdem modern angehauchten Atmosphäre empfangen. Im Erdgeschoss ist quasi der Imbiss-Bereich – wobei dies einen etwas negativen Touch hat, der hier wahrlich nicht angebracht ist.&lt;br /&gt;
Im hinteren Bereich erwartet einen dann eine Theke voller mediteraner Köstlichkeiten, welche einem direkt an einen italienischen Feinkosthändler erinnert. Da reihen sich feinste Antipasti neben selbstgemachten Pasten (z.B. Oliven) ein. Die Stars der Theke sind aber die x verschiedenen Käsesorten sowie de grosse Auswahl an verschiedenen Leckereien für den Fleischesser. Hier darf man nun also sein eigenes Focaccia zusammenstellen. Es gibt drei verschiedene Grössen, wobei zumindest ich für das Grösste schon einen rechten Hunger brauche. Dann kann man sich eine Fleisch- oder Käsesorte auswählen, zwei Antipasti sowie eine Paste. Salat (z.B. Ruccola) gibt’s gratis. Das Fleisch wird frisch angeschnitten und mit den anderen Zutaten in das erwärmte Focaccia gepackt. Nun noch ein prickelnd frisches &lt;a href="http://www.gazosa.info"&gt;Gazosa&lt;/a&gt; dazu, und die Ferien-Stimmung ist perfekt.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;img height="201" width="300" src="/images/blog_nettigkeiten_ch/DSC_0030.jpg" alt="" /&gt;  &lt;/p&gt;
&lt;p class="MsoNormal"&gt;(Bild focacceria.ch)&lt;br /&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Wer sich die schmale Treppe nach oben getraut, findet dort ein etwas eleganter aufgemachtes kleines Restaurant. Der obere Stock ist bedient. Man kann dort, neben den Focaccias auch von einer sehr kleinen aber feinen Karte aussuchen. Die Karte wird täglich geändert und offeriert einem gluschtige Tagliatelle, Suppen und Salate. Nach dem Essen sollte man sich unbedingt auf einen Dolci-Vorschlag der Bedienung einlassen, da gibt’s wirkliche Leckereien darunter.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Alles in allem ein wirklich gelungenes Lokal welches die totale Italianità versprüht. Die Preise sind zwar nicht ganz ohne, aber dafür erhält man auch wirklich qualitativ hervorragende Lebensmittel sehr gut zubereitet.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;img height="448" width="300" src="/images/blog_nettigkeiten_ch/DSC_0091.jpg" alt="" /&gt;&lt;img height="448" width="300" src="/images/blog_nettigkeiten_ch/DSC_0011.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;(Bilder focacceria.ch)&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Die Focacceria befindet sich an der Metzgergasse 22, 9000 St. Gallen.&lt;br /&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt; &lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://blog.nettigkeiten.ch/aggbug/211.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://blog.nettigkeiten.ch/comments/211.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.nettigkeiten.ch/comments/commentRss/211.aspx</wfw:commentRss>
        <trackback:ping>http://blog.nettigkeiten.ch/services/trackbacks/211.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Alles neu!</title>
        <link rel="self" type="text/html" href="http://blog.nettigkeiten.ch/archive/2008/07/17/alles-neu.aspx" />
        <id>http://blog.nettigkeiten.ch/archive/2008/07/17/alles-neu.aspx</id>
        <published>2008-07-17T23:06:3202:00:00</published>
        <updated>2008-07-22T16:06:22Z</updated>
        <content type="html">Tattaaa! Happy New Year! Der erste Post 2008! Naja... ist ja erst Mitte Jahr &lt;img src="/Providers/BlogEntryEditor/FCKeditor/editor/images/smiley/msn/embaressed_smile.gif" alt="" /&gt;&lt;br /&gt;
&lt;br /&gt;
Die üblichen Entschuldigungen spar ich mir mal und konzentrier mich hier lieber auf die wichtigen Sachen. Ich habe mich, wie so manche andere auch in letzter Zeit, von &lt;a href="http://www.dasblog.info"&gt;dasBlog&lt;/a&gt; verabschiedet und mich für &lt;a href="http://www.subtextproject.com"&gt;SubText&lt;/a&gt; entschieden.&lt;br /&gt;
&lt;br /&gt;
Die Umstellung war recht harzig und mühsam und mit diversen Stolpersteinen versehen. Aber zum Glück gibts ja nette Leute die ihre Erfahrungen der Öffentlichkeit hinterlassen. Allen voran sei hier &lt;a href="http://www.ayende.com/Blog/archive/2007/02/03/From-DasBlog-To-SubText.aspx"&gt;Oren Eini&lt;/a&gt; erwähnt, der sogar das UrlRewriting von SubText erweitert hat, so dass auch die meisten alten dasBlog-Links noch funktionieren sollten.&lt;br /&gt;
&lt;br /&gt;
Solltet ihr trotzdem etwas nicht finden, dass noch nicht funktioniert, wär ich um eine kurze Meldung dankbar.&lt;br /&gt;
&lt;br /&gt;
Auch wenn die alten Links dank Oren noch funktionieren sollten, passt eure Einstellungen doch trotzdem bitte auf die neue URL &lt;a href="http://blog.nettigkeiten.ch"&gt;http://blog.nettigkeiten.ch&lt;/a&gt; an.&lt;br /&gt;
&lt;br /&gt;
Schon komisch... da gibt's ein halbes Jahr lang kein Lebenszeichen, und kaum muss ich ins Militär, gibt's grad einen Relaunch... &lt;img src="/Providers/BlogEntryEditor/FCKeditor/editor/images/smiley/msn/wink_smile.gif" alt="" /&gt; Naja, mal schauen, je nach Lage an der Front reichts dann vielleicht auch noch gleich für ein bisschen "anmalen".&lt;img src="http://blog.nettigkeiten.ch/aggbug/210.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://blog.nettigkeiten.ch/comments/210.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.nettigkeiten.ch/comments/commentRss/210.aspx</wfw:commentRss>
        <trackback:ping>http://blog.nettigkeiten.ch/services/trackbacks/210.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Adventskalender bei entwickler-press.de</title>
        <link rel="self" type="text/html" href="http://blog.nettigkeiten.ch/archive/2007/12/01/adventskalender-bei-entwickler-press.de.aspx" />
        <id>http://blog.nettigkeiten.ch/archive/2007/12/01/adventskalender-bei-entwickler-press.de.aspx</id>
        <published>2007-12-01T14:22:1701:00:00</published>
        <updated>2007-12-01T14:22:17Z</updated>
        <content type="html">&lt;p&gt;Heute schiessen ja die Adventskalender auf den verschiedensten WebSites geradezu aus dem Boden. Einer, dessen Besuch sich wirklich lohnt, ist auf &lt;a href="http://entwickler-press.de/" target="_blank"&gt;entwickler-press.de&lt;/a&gt; zu finden. Dort gibts nämlich jeden Tag ein eBook gratis und franko zum Download, ja man muss sich noch nicht mal registrieren.&lt;/p&gt; &lt;p&gt;Heute gibts &lt;a href="http://www.amazon.de/Managed-DirectX-Einstieg-professioneller-Einsatz/dp/3939084174/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1196518914&amp;amp;sr=8-1" target="_blank"&gt;Managed Direct X und C#&lt;/a&gt;. &lt;/p&gt;&lt;img src="http://blog.nettigkeiten.ch/aggbug/149.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://blog.nettigkeiten.ch/comments/149.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.nettigkeiten.ch/comments/commentRss/149.aspx</wfw:commentRss>
        <trackback:ping>http://blog.nettigkeiten.ch/services/trackbacks/149.aspx</trackback:ping>
    </entry>
    <entry>
        <title>KeePass und Ubuntu</title>
        <link rel="self" type="text/html" href="http://blog.nettigkeiten.ch/archive/2007/12/01/keepass-und-ubuntu.aspx" />
        <id>http://blog.nettigkeiten.ch/archive/2007/12/01/keepass-und-ubuntu.aspx</id>
        <published>2007-12-01T14:09:5101:00:00</published>
        <updated>2007-12-01T14:09:51Z</updated>
        <content type="html">&lt;p&gt;&lt;a href="http://keepass.info/" target="_blank"&gt;KeePass&lt;/a&gt; war mir unter Windows ein ständiger Begleiter und passte für mich perfekt zur Verwaltung meiner Passwörter. Mittlerweile ist meine Passwort-Datenbank auch schon recht angewachsen... blöd nur, dass es das Ding nur für Windows gibt.&lt;/p&gt; &lt;p&gt;Trotzdem - mal googlen... aah... &lt;/p&gt; &lt;p&gt;&lt;a title="KeePassX" href="http://www.keepassx.org" target="_blank"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="183" alt="keypassx" src="Images/82_195_229_7/daninet/keypassx_3.png" width="182" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;KeePassX, eine Portierung von KeePass für Linux- und Mac-Systeme - und ja, es kann die KeePass-Datenbanken lesen - und auch umgekehrt. So kann ich also weiterhin die bestehende Datenbank nutzen und diese unter Linux mit KeePassX und unter Windows mit KeePass lesen.&lt;/p&gt; &lt;p&gt;&lt;a href="http://keepass.info/" target="_blank"&gt;KeePass&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.keepassx.org/" target="_blank"&gt;KeePassX&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blog.nettigkeiten.ch/aggbug/150.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://blog.nettigkeiten.ch/comments/150.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.nettigkeiten.ch/comments/commentRss/150.aspx</wfw:commentRss>
        <trackback:ping>http://blog.nettigkeiten.ch/services/trackbacks/150.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Ich geh fremd!</title>
        <link rel="self" type="text/html" href="http://blog.nettigkeiten.ch/archive/2007/11/28/ich-geh-fremd.aspx" />
        <id>http://blog.nettigkeiten.ch/archive/2007/11/28/ich-geh-fremd.aspx</id>
        <published>2007-11-28T20:34:3301:00:00</published>
        <updated>2007-11-28T20:34:33Z</updated>
        <content type="html">&lt;p&gt;Nachdem ich schon seit längerem ein Doppelleben führte, habe ich mich nun definitiv entschieden! Seit der Version 7.10 bin ich vollständig auf &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt; umgestiegen. Wieso denn das?&lt;/p&gt; &lt;p&gt;Durch mein Studium musste ich mich zwangsweise das eine oder andere Mal mit Linux auseinandersetzen, und je länger ich damit arbeitete, desto mehr stieg meine Begeisterung dafür. Die Arbeit damit ist einfach effizienter, die typischen Slow-Downs die ich unter Windows immer wieder hatte (Vista kann man fast als andauernden Slow-Down bezeichnen ;-) ) bleiben unter Linux eine wirkliche Seltenheit.&lt;/p&gt; &lt;p&gt;Dazu kommt noch, dass es eine ganze Menge an kleinen feinen Tools gibt, die natürlich allesamt Open-Source sind.&lt;/p&gt; &lt;p&gt;Natürlich komme ich, als .NET-Entwickler, nicht um Windows rum - aber dafür gibts ja VMWare. &lt;/p&gt;&lt;img src="http://blog.nettigkeiten.ch/aggbug/151.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://blog.nettigkeiten.ch/comments/151.aspx</wfw:comment>
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://blog.nettigkeiten.ch/comments/commentRss/151.aspx</wfw:commentRss>
        <trackback:ping>http://blog.nettigkeiten.ch/services/trackbacks/151.aspx</trackback:ping>
    </entry>
    <entry>
        <title>Eine professionelle Entwicklungsinfrastruktur f&amp;uuml;r (fast) lau (Teil 2 von 5) - IDE</title>
        <link rel="self" type="text/html" href="http://blog.nettigkeiten.ch/archive/2007/11/28/eine-professionelle-entwicklungsinfrastruktur-fuumlr-fast-lau-teil-2-von-5.aspx" />
        <id>http://blog.nettigkeiten.ch/archive/2007/11/28/eine-professionelle-entwicklungsinfrastruktur-fuumlr-fast-lau-teil-2-von-5.aspx</id>
        <published>2007-11-28T19:33:5301:00:00</published>
        <updated>2007-11-28T19:33:53Z</updated>
        <content type="html">&lt;p&gt;Mit knapp 2 Monaten Verspätung folgt nun also der zweite Teil dieser kleinen Serie :-)&lt;/p&gt; &lt;p&gt;Die IDE ist das meist täglich gebrauchte Werkzeug eines jeden Entwicklers. Unter .NET ist das mit Abstand am meisten verbreitete Exemplar dieser Gattung Visual Studio in den verschiedenen Ausprägungen. Wie bereits in Teil 1 geschrieben, erachte ich die Wahl der IDE als sekundär, Hauptsache der Entwickler findet sich damit zu Recht - also vergleichbar mit den Kochmessern eines Küchenchefs :-)&lt;/p&gt; &lt;p&gt;Dieser Artikel wird zeigen, wie man mittels Visual Studio 2008 seine Projekte mit UnitTests testet. UnitTests sollten genauso ein Selbstverständnis für einen Entwickler sein, wie auch alle anderen Punkte dieser Serie. Ich möchte hier nicht ins Detail gehen, das machen andere schon sehr gut - trotzdem aber die wichtigsten Punkte, um was es beim Unit-Testing geht. Zuerst also etwas Theorie.&lt;/p&gt; &lt;h3&gt;Definition&lt;/h3&gt; &lt;p&gt;Für ne schlaue Definition muss wiedermal &lt;a href="http://en.wikipedia.org/wiki/Unit_tests"&gt;Wikipedia&lt;/a&gt; herhalten:&lt;/p&gt; &lt;p&gt;&lt;em&gt;"(...) unit testing is a procedure used to validate that individual units of source code are working properly. A unit is the smallest testable part of an application."&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Also - man testet den kleinst-möglichen testbaren Teil einer Applikation - und das ist per Definition in einer OO-Anwendung natürlich die Methode. Dieser scheinbar unspektakuläre Satz, beeinhaltet schon einige der Grundsätze von Unit Tests.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Jeder Unit-Test testet genau eine Methode, nicht mehr und nicht weniger. Es werden also keine ganzen Abläufe (z.B. Abfolge von Method-Calls) getestet.  &lt;/li&gt;&lt;li&gt;Das Resultat eines Unit-Tests sagt aus, ob die Methode (und nur genau die) gemäss dem definierten Testfall korrekt funktioniert.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Unit-Tests sollten immer möglichst einfach gehalten werden, dies reduziert das Risiko von Fehler im Test selbst.&lt;/p&gt; &lt;h3&gt;Test-Driven Development&lt;/h3&gt; &lt;p&gt;Im Zusammenhang mit Unit-Tests wird oftmals von Test-Driven Development (TDD) gesprochen. Wie der Name schon sagt, geht es dabei darum, mittels Tests zur eigentlichen Implementation zu kommen. Neue Funktionen werden stets gegen die &lt;strong&gt;zuvor&lt;/strong&gt; definierten Testfälle implementiert und getestet. Eine Funktion gilt dann als implementiert, wenn diese alle für sie definierten Testfälle erfolgreich durchlaufen kann. In diesem Zusammenhang ebenfalls wichtige Konzepte sind&lt;/p&gt; &lt;ul&gt; &lt;li&gt;KISS - Keep it simple, stupid  &lt;/li&gt;&lt;li&gt;YAGNI - You ain't gonna need it&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Wichtiger Punkt im TDD ist also, nur genau das zu implementieren, was auch gefordert wird - und alles was gefordert wird, muss als Testfall hinterlegt sein. Jede Funktion die zusätzlich implementiert wird, quasi als gutgemeinten Bonus, ist nicht getestet (zumindest durch Unit-Tests) und stellt daher eine Verletzung dieser Prinzipien dar.&lt;/p&gt; &lt;h3&gt;Die Regeln des Test-Driven Development&lt;/h3&gt; &lt;p&gt;Der Ablauf beim TDD erscheint vielen Entwicklern anfangs etwas umständlich und gewöhnungsbedürftig. Auch scheinen die Regeln teils etwas überbestimmt. Trotzdem hat jede dieser Regeln ihre Berechtigung.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Schreibe den Test&lt;/strong&gt;&lt;br /&gt;Hier werden viele bereits stutzig. Den Test vor der eigentlichen Methode schreiben? Genau! Denn die Methode soll ja vom Test abhängen und nicht umgekehrt. Andersrum besteht immer die Gefahr, dass der Test um die Methode gebaut wird. Man testet das, was man weiss das die Methode kann - und nicht was sie können sollte.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Implementiere die Methode so, dass sie (und der zuvor definierte Test) gerade mal kompiliert, der Test aber fehlschlägt&lt;/strong&gt;&lt;br /&gt;Dieser Punkt wird oft ignoriert, da er so trivial erscheint. Der Punkt, dass der Test aber immer zuerst fehlschlagen soll, ist sehr zentral, da auch ein Test - wie jedes andere Stück Software auch - prinzipiell Fehler enthalten kann. Das heisst, der Test könnte immer erfolgreich sein, obwohl der Case gar nicht erfüllt ist. Dieser Punkt ist also quasi der Test des Tests.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Implementiere die Methode so, dass sie den Testfall besteht&lt;/strong&gt;&lt;br /&gt;Nun gehts also ans Eingemachte, die Methode soll ihre Implementation erhalten, und zwar so, dass sie den zuvor geschriebenen Test erfolgreich durchläuft. Wichtig dabei ist, dass hier noch nicht die ultimative Super-Lösung gebaut werden soll. Es soll in erster Linie mal einfach funktionieren. Nachdem in Punkt 2 ja getestet wurde, dass der Test fehlschlägt wenn er soll, muss jetzt ja auch mal gezeigt werden, dass er zu einer funktionierenden Methode auch sein "OK" gibt.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Refactor&lt;/strong&gt;&lt;br /&gt;Nun wird die laufende Lösung von Punkt 4 mittels Refactoring "verschönert". Der Test muss danach natürlich immer noch korrekt durchlaufen werden.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Starte wieder bei Punkt 1&lt;/strong&gt;&lt;br /&gt;Eine Methode hat in den seltensten Fällen nur einen Testfall. Da die Fälle sehr einfach gehalten werden sollen, gibt es hier meist ein ganzes Set von Tests pro Funktion. Dieser Punkt streicht den iterativen Ansatz dieser Methodik hervor. Die Implementation wächst also iterativ mit jedem Testfall, und ist genau dann fertig, wenn keine weiteren Fälle mehr zu definieren sind und alle definierten Fälle erfolgreich abgeschlossen werden können.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Wieso denn nun das ganze? Die Vorteile die aus dieser Vorgehensweise entstehen sollten für sich sprechen:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Fehlerfreie Software?&lt;/strong&gt;&lt;br /&gt;Nicht ganz - aber man weiss zumindest, und kann auch jederzeit nachprüfen, dass eine Funktion mit den definierten Testfällen klar kommt. Natürlich heisst das noch lange nicht, dass damit die Software korrekt funktioniert oder gar fehlerfrei ist. Jedoch kann man von einem gewissen Grad an Korrektheit ausgehen. Sollten trotzdem Fehler auftreten, waren die Testfälle nicht ausreichend.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Entspannte Änderungen&lt;/strong&gt;&lt;br /&gt;Jeder kennt das, man muss an einer Software etwas ändern und man ist sich vielleicht nicht ganz 100%ig über die Konsequenzen im Klaren. Side-Effects treten ja meist an den Stellen auf, an denen man sie am wenigsten vermutet. Kann der Entwickler jedoch nach seiner Änderung auf eine Fülle von erfolgreich abgearbeiteten Testfälle blicken, wird das sein Vertrauen merklich steigern. Auch hier gilt aber natürlich Vorsicht, die Änderung kann trotzdem Fehler verursachen! Evtl. müssen für die Änderung auch neue Tests eingeführt werden.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Dokumentation&lt;/strong&gt;&lt;br /&gt;Auch diese Situation ist wohl den meisten bekannt - man hat eine Methode vor sich und kann irgendwie nicht so greifen, was diese überhaupt genau macht. Die "erklärenden" Sätze in den Kommentaren machen das ganze auch nicht einfacher. Die Testfälle hingegen zeigen mit sehr übersichtlichem und einfachem Code, was die Methode zu erfüllen hat.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Lose Kopplung&lt;/strong&gt;&lt;br /&gt;Dies kommt praktisch gratis mit TDD mit. Denn wer so vorgeht, wird automatisch wenig Abhängigkeiten erzeugen. Abhängigkeiten sind immer irgendwo problematisch beim testen - da wird man sich also hüten.&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;Die Krux mit den Abhängigkeiten&lt;/h3&gt; &lt;p&gt;Wie bereits geschrieben, sind Abhängigkeiten ein grundsätzliches Problem beim Unit-Testing. Man stelle sich zum Beispiel vor, man möchte eine Methode einer Datenbankzugriffsklasse testen. Beim schlichten Aufruf dieser Methode wird automatisch auch die Datenbank aufgerufen. Was test man so nun? Funktioniert das Db-Statement? Ist die Datenbank erreichbar? Oder doch nur ob die Funktion korrekt funktioniert? Ja genau - alles zusammen, und doch wieder nichts. Wenn was schief geht, ist nicht klar warum. Daraus ergeben sich einige Grundregeln, die man beim Schreiben der Tests beachten sollte:&lt;/p&gt; &lt;p&gt;Ein Unit-Test sollte nie&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I/O-Funktionalität aufrufen (Filesysteme, Datenbanken, Netzwerk... alles tabu)  &lt;/li&gt;&lt;li&gt;auf ein Konfigurations-File angewiesen sein  &lt;/li&gt;&lt;li&gt;von anderen Unit-Tests abhängig sein. Jeder Test muss für sich allein funktionieren.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Solche Abhängigkeiten werden mit Hilfe von &lt;a href="http://en.wikipedia.org/wiki/Mock_object"&gt;Mock-Objekten&lt;/a&gt; nachgebaut. Hierzu wird nächstens ein eigener kleiner Artikel folgen.&lt;/p&gt; &lt;p&gt;Wer all dies berücksichtigt - wird glücklich mit TDD - da leg ich meine Hand ins Feuer :-)&lt;/p&gt; &lt;h3&gt;TDD mit Visual Studio 2008&lt;/h3&gt; &lt;p&gt;Das neue Visual Studio (wie auch das alte :-) ) bietet alles, was man zu TDD benötigt. Zur Veranschaulichung ziehen wir mal so ein Szenario durch. Als Beispiel dient uns eine Applikation, die beliebige Zeichenketten durch verschiedene Sortieralgorithmen sortieren kann - so zum Beispiel mit QuickSort, ein beliebter "Divide and Conquer"-Algorithmus.&lt;/p&gt; &lt;p&gt;Als Ausgangslage dient uns folgender Aufbau der Applikation:&lt;/p&gt; &lt;p&gt;&lt;a href="Images/82_195_229_7/daninet/solutionexplorer_start_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" alt="solutionexplorer_start" src="Images/82_195_229_7/daninet/solutionexplorer_start_thumb.png" width="219" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Program.cs beinhaltet etwas Code zur Verarbeitung der Eingabe sowie die schlussendliche Ausgabe des Resultates. ISortAlgorithm ist ein Interface, welches die Schnittstellen eines Sortieralgorithmus' vorgibt - nämlich:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISortAlgorithm
&lt;/span&gt;{
  &lt;span style="color: blue"&gt;string &lt;/span&gt;Sort(&lt;span style="color: blue"&gt;string &lt;/span&gt;toSort);
}&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Nun haben wir ja vorhin einen schönen Ablauf definiert, also sehen wir mal ob der was taugt:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Punkt 1 - Test schreiben:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;An dieser Stelle erlaube ich mir bereits die erste kleine Abweichung obiger Regel. Und zwar erstelle ich mir jeweils aus Bequemlichkeit bereits die Klasse sowie den Methodenrumpf bevor ich den Test schreibe. Das hat den Vorteil, das man beim Test schreiben auf IntelliSense zurückgreifen kann und nicht alles komisch rot unterstrichen erscheint. Ausserdem kann man sich das Gerüst für die Tests gleich in Visual Studio generieren lassen.&lt;/p&gt;
&lt;p&gt;Ich erstelle also die Klasse QuickSortAlgorithm und implementiere das obige Interface ISortingAlgorithm. Das ist's dann aber auch schon. Danach genügt ein Rechtsklick ins Fenster zum Erstellen des Test-Projektes.&lt;/p&gt;
&lt;p&gt;&lt;a href="Images/82_195_229_7/daninet/createtestproject_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="290" alt="createtestproject" src="Images/82_195_229_7/daninet/createtestproject_thumb.png" width="284" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="Images/82_195_229_7/daninet/createtestproject_dialog_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="272" alt="createtestproject_dialog" src="Images/82_195_229_7/daninet/createtestproject_dialog_thumb.png" width="404" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;In dem generierten File findet sich dann eine Methode SortTest. Dies ist nun also unser Test, dessen Logik wir nun noch zu definieren haben.&lt;/p&gt;&lt;pre class="code"&gt;       [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;()]
&lt;span style="color: blue"&gt;       public void &lt;/span&gt;SortTest()
       {
            &lt;span style="color: #2b91af"&gt;QuickSortAlgorithm &lt;/span&gt;target = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;QuickSortAlgorithm&lt;/span&gt;(); &lt;span style="color: green"&gt;// TODO: Initialize to an appropriate value
            &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;toSort = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Empty; &lt;span style="color: green"&gt;// TODO: Initialize to an appropriate value
            &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;expected = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Empty; &lt;span style="color: green"&gt;// TODO: Initialize to an appropriate value
            &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;actual;
            actual = target.Sort(toSort);
            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(expected, actual);
            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Inconclusive(&lt;span style="color: #a31515"&gt;"Verify the correctness of this test method."&lt;/span&gt;);
        }&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Das TestMethod-Attribut gibt an, dass es sich bei der Methode um einen Test handelt. Dies ist notwendig, damit Visual Studio damit zu Recht kommt.&lt;/p&gt;
&lt;p&gt;Um dies zu tun, muss man sich natürlich über die Anforderungen im Klaren sein. Unit-Tests sind WhiteBox-Tests - der Entwickler weiss also von der Implementation, dies ist auch nötig, wie wir später noch sehen werden. Also die Anforderung ist, dass wir der Methode einen String übergeben können und dieser sortiert zurück kommt. Entsprechend passen wir den Test an:&lt;/p&gt;&lt;pre class="code"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;()]
        &lt;span style="color: blue"&gt;public void &lt;/span&gt;SortTest()
        {
            &lt;span style="color: #2b91af"&gt;QuickSortAlgorithm &lt;/span&gt;target = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;QuickSortAlgorithm&lt;/span&gt;();
            &lt;span style="color: blue"&gt;string &lt;/span&gt;toSort = &lt;span style="color: #a31515"&gt;"bda"&lt;/span&gt;;
            &lt;span style="color: blue"&gt;string &lt;/span&gt;expected = &lt;span style="color: #a31515"&gt;"abd"&lt;/span&gt;;
            &lt;span style="color: blue"&gt;string &lt;/span&gt;actual;
            actual = target.Sort(toSort);
            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(expected, actual);
        }&lt;/pre&gt;
&lt;p&gt;Sehr schlicht und einfach also das ganze. Gut - und nun zu Punkt 2.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Punkt 2 - Methode implementieren, dass der Test fehlschlägt&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Einfach, aber wichtig - also, wir geben einen Wert zurück, der den Test dazu veranlassen müsste, fehlzuschlagen - also zum Beispiel einen Leerstring.&lt;/p&gt;
&lt;p&gt;Nun lassen wir den Test ein erstes Mal laufen um zu schauen, ob das Erwartete auch wirklich eintrifft. Ein Weg den Test zu starten ist wiederum über das Kontextmenü der Testmethode:&lt;/p&gt;
&lt;p&gt;&lt;a href="Images/82_195_229_7/daninet/runtests_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="190" alt="runtests" src="Images/82_195_229_7/daninet/runtests_thumb.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Und erhält folgendes Resultat:&lt;/p&gt;
&lt;p&gt;&lt;a href="Images/82_195_229_7/daninet/testresult_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="101" alt="testresult" src="Images/82_195_229_7/daninet/testresult_thumb.png" width="404" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Wenn das Resultat hier auf "Passed" wäre, wüsste man nun, dass der Test noch fehlerhaft ist, da er offensichtlich falsche Daten also korrekt klassifizierte.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Auf die restlichen Punkte muss hier nicht genauer eingegangen werden. Nun geht es einfach noch darum, die Implementation korrekt zu machen, und weitere Testfälle zu definieren, die sicherstellen, dass der Algorithmus korrekt funktioniert. &lt;/p&gt;
&lt;p&gt;Weitere Testfälle wären zum Beispiel:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;weitere Strings die korrekt sortiert werden müssen (spezielle Daten!), erwartet korrekt sortierte Rückgaben 
&lt;/li&gt;&lt;li&gt;ein Leerstring als Übergabe, erwartet einen Leerstring als Rückgabe 
&lt;/li&gt;&lt;li&gt;null als Übergabe, erwartet eine NullReferenceException 
&lt;/li&gt;&lt;li&gt;usw.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Das Beispiel mit einigen definierten Testfällen gibt's zum Download.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;Code Coverage&lt;/h3&gt;
&lt;p&gt;Die Code Coverage gibt an, wieviel Prozent der Code-Statements durch einen Test abgedeckt werden. Dieser Wert sagt zwar prinzipiell nicht sehr viel aus, man sollte die Coverage aber dennoch immer etwas im Auge behalten. Ziel sollte ein Wert jenseits der 90%-Marke sein.&lt;/p&gt;
&lt;p&gt;Mit Visual Studio lässt sich die Code Coverage sehr einfach messen. Hierzu müssen aber zuerst die Assemblies ausgewählt werden, auf denen die Messung stattfinden soll. Das entsprechende Menu findet man hier:&lt;/p&gt;
&lt;p&gt;&lt;a href="Images/82_195_229_7/daninet/editconfig_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="169" alt="editconfig" src="Images/82_195_229_7/daninet/editconfig_thumb.png" width="404" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="Images/82_195_229_7/daninet/editconfig2_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="356" alt="editconfig2" src="Images/82_195_229_7/daninet/editconfig2_thumb.png" width="504" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Danach kann man, nachdem die Tests durchgeführt wurden, das Code Coverage-Fenster öffnen und sich die Resultate zu Gemüte führen.&lt;/p&gt;
&lt;p&gt;&lt;a href="Images/82_195_229_7/daninet/showcov_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="282" alt="showcov" src="Images/82_195_229_7/daninet/showcov_thumb.png" width="404" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;In dem Fenster kann man sich dann auch gleich anzeigen lassen, welche Zeilen durch einen Test abgedeckt werden und welche nicht. So kann man seine Testfälle optimieren.&lt;/p&gt;
&lt;p&gt;&lt;a href="Images/82_195_229_7/daninet/resultscov_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="442" alt="resultscov" src="Images/82_195_229_7/daninet/resultscov_thumb.png" width="604" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Dies zeigt nun auch, wieso Unit-Tests eben WhiteBox-Tests sein müssen. Damit die Testfälle alle Verzweigungen einer Methode berücksichtigen kann, muss der Entwickler des Testfalls wissen, wie die Methode implementiert ist.&lt;/p&gt;
&lt;p&gt;Natürlich sagt eine CodeCoverage von 100% nicht sonderlich viel aus - es ist weder ein Qualitätsmerkmal für den Code noch für die Testfälle. Es geht dabei mehr darum, zu entdecken, ob gewisse Code-Teile nicht getestet werden.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;Fazit&lt;/h3&gt;
&lt;p&gt;Unit Tests und TDD sind ein grosses und wichtiges Thema. Visual Studio ermöglicht einen komfortablen Einsatz. Seit der 2008-Version, weden Unit-Tests bereits in der Professional-Variante unterstützt. Allerdings geht es auch ohne - Tools hierfür gibt es wie Sand am Meer. Erwähnt seien hier &lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt;, &lt;a href="http://www.ncover.com/"&gt;NCover&lt;/a&gt; und &lt;a href="http://www.testdriven.net/"&gt;TestDriven.Net&lt;/a&gt; (kostenpflichtig).&lt;/p&gt;
&lt;p&gt;Viel braucht es also nicht, um Test-Driven entwickeln zu können. Trotzdem stellt sich der Anfang als eher harzig heraus, da es doch eine etwas andere Denk- und Vorgehensweise erfordert. Die Vorteile überwiegen aber doch klar, und wer sich einmal daran gewöhnt hat, wird es nicht mehr missen wollen.&lt;/p&gt;
&lt;p&gt;Und hier noch das Beispiel-Programm zum Download: &lt;br /&gt;
&lt;a href="Images/82_195_229_7/daninet/StringSort.zip"&gt;StringSort.zip (57.99 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;Referenzen&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Unit_tests"&gt;Unit Tests (Wikipedia)&lt;/a&gt; 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;Test-Driven Development (Wikipedia)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;h3&gt;Literatur&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.manning.com/osherove/"&gt;The art of unit testing, Roy Osherove&lt;/a&gt; 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Test-Driven-Development-Microsoft-NET-Professional/dp/0735619484/ref=sr_1_5?ie=UTF8&amp;amp;s=books&amp;amp;qid=1196279765&amp;amp;sr=1-5"&gt;Test-Driven Development in .NET, James W. Newkirk, Alexei A. Vorontsov&lt;/a&gt; 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Professional-Software-Testing-Visual-Studio/dp/0470149787/ref=sr_1_7?ie=UTF8&amp;amp;s=books&amp;amp;qid=1196279765&amp;amp;sr=1-7"&gt;Professional Software Testing with Visual Studio 2005 VS, Tom Arnold, Dominic Hopton, Andy Leonard, Mike Frost&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://blog.nettigkeiten.ch/aggbug/152.aspx" width="1" height="1" /&gt;</content>
        <wfw:comment>http://blog.nettigkeiten.ch/comments/152.aspx</wfw:comment>
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.nettigkeiten.ch/comments/commentRss/152.aspx</wfw:commentRss>
        <trackback:ping>http://blog.nettigkeiten.ch/services/trackbacks/152.aspx</trackback:ping>
    </entry>
</feed>