- What is NSynthesis?
- Prerequisites
- Usage
- Extending NUnit
- Patching your test project's csproj file
- Add Watch Attributes
- Running tests from nant
- Generating the NSynthesis report
- Running the sample app
- Known Limitations and Quirks
What is NSynthesis?
In practical terms, NSynthesis monitors your unit tests as they run, capturing any calls you make to a mock object. For each call to a mock, NSynthesis demands that you have executed every possible concrete implementation during the same test run. NSynthesis uses PostSharp to modify the test code only, so there are no changes required to your production code base.
There are also implementations for Ruby and Java.
Prerequisites
Currently, NSynthesis requires that you are using the following tools
- NUnit 2.5
- Rhino Mocks
- Nant
Let us know what other tools you'd like support for.
Usage
You do not need to modify any production code. If you do, let us know and we'll try and change it. You will need to modify your test code and build scripts.
If in doubt, follow the example of the project Sample.Test.
Steps to get NSynthesis working are:
- Add the NSynthesis Extension to nunit
- Patch your test project's csproj file
- Add watch attributes for the production classes
- Run your unit tests in using the <exec> nant task
- Call the <nsynthesis> nant task to get the results.
Extending NUnit
Copy the file NSynthesis.NUnitExtension.dll to [path-to-nunit]\addins\NSynthesis.NUnitExtension.dll.
Patching your test project's csproj file
In the unit test project's .csproj file, replace
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.-->
with
<PropertyGroup> <DontImportPostSharp>True</DontImportPostSharp> <PostSharpAutoUpdateDisable>True</PostSharpAutoUpdateDisable> </PropertyGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.--> <Import Project="path\to\PostSharp.targets" />
NB: Make sure the relative path to "path\to\PostSharp.targets" is correct.
In the unit test project, add references to NSynthesis.dll, PostSharp.Public.dll and PostSharp.Laos.dll.
Add Watch Attributes
Somewhere in your unit test assembly's code (we suggest the AssemblyInfo.cs file), include the Watch attribute e.g.
[assembly: Watch(AttributeTargetAssemblies = "YourApplication", AttributeTargetTypes="*")]
That example would submit all types in the MainApplication to NSynthesis' inspection.
If you want generic classes to be examined, change your Watch attribute as follows:
[assembly : Watch(AttributeTargetAssemblies = "YourApplication", AttributeTargetTypes = "*", MonitorGenerics = true)]
Running tests from nant
Ensure that you are calling nunit using the nant exec command (you cannot use the NUnit2 task)
e.g
<exec program="${nunit-console.exe}">
<arg value="path\to\my\Test.dll" />
<arg value="/xml=Test-Results.xml" />
</exec>The nunit2 task does not support nunit addins, and so cannot generate the nsynthesis report file.
Generating the NSynthesis report
Include the following in your NAnt script, after you've run the unit tests.
<target name="synthesis"> <loadtasks assembly="path\to\NSynthesis.Tasks.dll" /> <NSynthesis reportFile="synthesis.xml" failonerror="true" /> </target>
When the synthesis target runs, it will dump a report to the command line of how many mock calls it found, and if any of them had no implementations or any untested implementations.
Running the sample app
In the folder sample, run sample.bat. This demonstrates a build passes because of there are unit tests for all mocked interactions. Try disabling one or more of the repository tests to break the build.
Known Limitations and Quirks
- Currently only one test run is supported, there is no way to chain tests
- There is no way to configure the synthesis.xml output file is generated