I have two separate namespaces in my assembly: DataAccess and DomainLogic.
I need a code snippet checking that no class in DomainLogic depends on the namespace DataAccess.
How would you dou it?
PS: I think I saw an example for such a unit test in Mark Seemann's awesome book Dependency Injection in .Net, but I don't have it available here and can't find an example via Google.
Edit
Since all reactions so far point out that I should just split these interdependent classes into two different assemblies, I would like to point out that this is currently not an option (although this is indeed one of my main goals in the end). I'm dealing with legacy code and I just can't refactor it in one big bang right now. The separate namespaces and the test for dependencies between them are an intermediate step. As soon as that test passes, I can go ahead and move a part of the code into a different assembly.
All code within an assembly can legitimately access public and internal code throughout the rest of the assembly. So such unit tests, even if possible, would be a bad idea.
If you split the DataAccess types out into a separate project and made it all internal, then nothing would be able to access it. Clearly not what you'd want. However, by splitting it out, you can ensure that DomainAccess can access DomainLogic, but not vice versa. This presumably is what you want.
In the meantime, rather than try to develop unit tests to check that the rule of "DomainLogic must not access DomainAccess", use code reviews instead. Assuming you are using agile methods (if not, do so!), all activities will be documented as tasks. No task can be considered "done" until someone who understands and embraces your rule has reviewed the code changes for a task. Break the rule and the task fails code review and must be reworked before it's done.
There's a tool that does just this: checks namespace dependencies based on your rules and reports violations at build-time as warnings or errors.
It's called NsDepCop, free, open-source.
The rule config would look something like this:
<NsDepCopConfig IsEnabled="True" CodeIssueKind="Warning">
<Allowed From="*" To="*" />
<Disallowed From="DomainLogic" To="DataAccess" />
</NsDepCopConfig>
Related
I'm using NDepend to analyze a C# project that I'm in the middle of developing. I have most of my business logic and data access layers written, but right now, the only front end application that I have is a "quick and dirty" test application.
So first off, NDepend has all kinds of issues with my test application. Nothing serious, just things like too many methods, too-long methods, etc. Since this is basically a throwaway application, I didn't want to spend a bunch of time refactoring it, so I removed it from the NDepend project.
The problem is that now, since that was my only front end application in the project, NDepend is complaining about things in my business layer like uninstantiated classes, since there is no code that instantiates them except in the test application that I've excluded. I know that these are safe to ignore for now, since they will eventually be instantiated by the REAL front end app, but I really really want to see all of the yellow triangles go away before I do any further development on this app.
Is there a way to make NDepend NOT complain about issues in a particular assembly, but still include it to make queries in OTHER assemblies pass?
If not, any other ideas?
Yes it is possible. First reference again your test application assembly(ies).
Then exclude them by adding a custom query that look like:
// <Name>Discard test assemblies from JustmyCode</Name>
notmycode Application.Assemblies.WithNameIn("TestAsm1","TestAsm2"...)
This query can be saved in the default group Defining JustMyCode (not mandatory but recommended).
Then you need to adapt code rules that are warning about test assemblies dirty stuff to use JustMyCode instead of Application (like from m in JustMyCode.Methods... instead of from m in Application.Methods...).
The notmycode/JustmyCode related documentation can be found here.
I'm writing a library that has a bunch of classes in it which are intended to be used by multiple frontends (some frontends share the same classes). For each frontend, I am keeping a hand edited list of which classes (of a particular namespace) it uses. If the frontend tries to use a class that is not in this list, there will be runtime errors. My goal is to move these errors to compile time.
If any of you are curious, these are 'mapped' nhibernate classes. I'm trying to restrict which frontend can use what so that there is less spin up time, and just for my own sanity. There's going to be hundreds of these things eventually, and it will be really nice if there's a list somewhere that tells me which frontends use what that I'm forced to maintain. I can't seem to get away with making subclasses to be used by each frontend and I can't use any wrapper classes... just take that as a given please!
Ideally, I want visual studio to underline red the offending classes if someone dares to try and use them, with a nice custom error in the errors window. I also want them GONE from the intellisense windows. Is it possible to customize a project to do these things?
I'm also open to using a pre-build program to analyze the code for these sorts of things, although this would not be as nice. Does anyone know of tools that do this?
Thanks
Isaac
Let's say that you have a set of classes F. You want these classes to be visible only to a certain assembly A. Then you segregate these classes in F into a separate assembly and mark them as internal and set the InternalsVisibleTo on that assembly to true for this certain assembly A.
If you try to use these classes from any assembly A' that is not marked as InternalsVisibleTo from the assembly containing F, then you will get a compile-time error if you try to use any class from F in A'.
I also want them GONE from the intellisense windows. Is it possible to customize a project to do these things?
That happens with the solution I presented above as well. They are internal to the assembly containing F and not visible from any assembly A' not marked as InternalsVisibleTo in the assembly containing F.
However, I generally find that InternalsVisibleTo is a code smell (not always, just often).
You should club your classes into separate dlls / projects and only provide access to those dlls to front end projects that are 'appropriate' for it. This should be simple if your front-end and the group of classes it may use are logically related.
If not then I would say some thing smells fishy - probably your class design / approach needs a revisit.
I think you'll want to take a look at the ObsoleteAttribute: http://msdn.microsoft.com/en-us/library/system.obsoleteattribute%28v=VS.100%29.aspx
I believe you can set IsError to true and it will issue an error on build time.
(not positive though)
As for the intellisense you can use EditorBrowseableAttribute: http://msdn.microsoft.com/en-us/library/system.componentmodel.editorbrowsableattribute.aspx Or at least that is what seems to get decorated when I add a service reference and cannot see the members.
When working with legacy code, and trying to create tests, I often break out dependencies from classes or methods so I can write unit tests using mocks for these dependencies. Dependencies most often come in the form of calls to static classes and objects created using the new keyword in the constructor or other locations in that class.
In most cases, static calls are handled either by wrapping the static dependency, or if its a singleton pattern (or similar) in the form of StaticClass.Current.MethodCall() passing that dependency by its interface go the constructor instead.
In most cases, uses of the new keyword in the constructor is simply replaced by passing that interface in the constructor instead.
In most cases, uses of the new keyword in other parts of the class, is handled either by the same method as above, or by if needed create a factory, and pass the factory's interface in the constructor.
I always use Resharpers refactoring tools to help me all of these break-outs, however most things are still manual labour (which could be automated), and for some legacy classes and methods that can be a very very tedious process. Is there any other refactoring plugins and/or tools which would help me in this process? Is there a "break out all depencencies from this class in a single click" refactoring tool? =)
It sounds to me like all these steps are common for many developers and a common problem, and before I attempt writing plugin to Resharper or CodeRush, I have to ask, because someone has probably already attempted this..
ADDED:
In reflection to answers below: even if you might not want to break out everything at once (one click total break out might cause more problems than it helps) still being able to simply break out 1 methods dependencies, or 1-2 dependencies easily, would be of big difference.
Also, refactoring code has a measure of "try and see what happens just to learn how everything fits together", and a one click total break out would help that process tons, even if you dont check that code in..
I don't think there is any tool that can automate this for you. Working with legacy code means -as you know- changing code with little steps at a time. The steps are often deliberately small to prevent errors from being made. Usually the first change you should make is one that makes that code testable. After you've written the test you change that part of the code in such way that you fix the bug or implement the RFC.
Because you should take small steps I believe it is hard to use a refactoring tool to magically make all your dependencies disappear. With legacy systems you would hardly ever want to make big changes at once, because the risk of breaking (and not finding out because of the lack of tests) is too big. This however, doesn’t mean refactoring tools aren’t useful in this scenario. On the contrary; they help a lot.
If you haven't already, I'd advise you to read Michael Feathers' book Working Effectively with Legacy Code. It describes in great details a series of patterns that help you refactor legacy code to a more testable system.
Good luck.
When it comes to static call dependencies, you might want to check out Moles. It's able to do code injection at run-time to stub out any static or non-virtual method call with your own test implementation. This is handy for testing legacy code that wasn't designed using testable dependency-injected interfaces.
I am trying to get a handle on the best practice for code
organization within my project. I have looked around on
the internet for good examples and, so far, I have seen
examples of a web project with one or multiple supporting
class libraries that it references or a web project with
sub-folders that follow its namespace conventions.
Assuming there is no right answer, this is what I currently
have for code organization:
MyProjectWeb
This is my web site. I am referencing my class libraries here.
MyProject.DLL
As the base namespace, I am using this DLL for files that
need to be generally consumable. For example, my class "Enums"
that has all the enumerations in my project lives there. As
does class MyProjectException for all exception handling.
MyProject.IO.DLL
This is a grouping of maybe 20 files that handle file upload and
download (so far).
MyProject.Utilities.DLL
ALl my common classes and methods bunched up together in one
generally consumable DLL. Each class follows a "XHelper" convention
such as "SqlHelper, AuthHelper, SerializationHelper, and so on...
MyProject.Web.DLL
I am using this DLL as the main client interface.
Right now, the majority of class files here are:
1) properties (such as School, Location, Account, Posts)
2) authorization stuff ( such as custom membership, custom role,
& custom profile providers)
My question is simply - does this seem logical?
Also, how do I avoid having to cross reference DLLs from one
project library to the next? For example, MyProject.Web.DLL
uses code from MyProject.Utilities.DLL and MyProject.Utilities.DLL
uses code from MyProject.DLL. Is this solved by clicking on properties and selecting "Dependencies"? I tried that but still don't seem to be accessing the namespaces of
the assembly I have selected. Do I have to reference every
assembly I need for each class library?
Responses appreciated and thanks for your patience.
It is logical in that it proceeds logically from your assumptions. The fact that you are asking the question leads me to believe you might not think it is rational.
In general, things should be broken down along conceptual boundaries rather than technical ones. MyProject.IO.DLL is an example of this principle surfacing in your current design. All of the IO things logically go together, so they end up in a single binary. Makes sense.
Breaking things down into namespaces based on their technical type - enum, class, etc. - is going to be a little more problematic.
The dependencies problem is the same one you'd have breaking one class up with many and it is resolved using the same technique: inversion of dependency. Where two things seemingly need to depend on one another, add an intermediary thing that represents the contract between the first two. This can be abstractions, constants, mediators etc... whatever you need to make it so that instead of thing A depending on thing B and thing B depending on thing A, you have things A and B depending on thing C.
I thought it will be a common question so I searched for a while but couldn't find it.
I am about to start a new project (C#, .net 3.5) and I was thinking about where I should I write the unit test code. I can create a unit test project and write all code there, or I can write the unit test code with the "class under test" itself.
What do you recommend and why? Things to consider before choosing an approach (caveats?)?
EDIT: About writing unit-test code with "code under test": Removing the test code from production assembly isn't difficult I guess. Thats what conditional compilation is for. Right?
Just throwing this point because answers are rejecting the second option just because production assemblies would be fatty.
Separate project, same solution. Use InternalsVisibleTo if you want to access internals from the test code.
Separating out test from production code:
makes it more obvious what's what
means you don't need dependencies on test frameworks in your production project
keeps your deployed code leaner
avoids including test data files in your deployment assembly
Keeping the code in the same solution:
keeps the test cycle quick
makes it easy to hop between production and test code
I always create a separate project in where I write my TestFixtures.
I do not want to litter my domain model (or whatever) with Test classes.
I do not want to distribute my tests to customers or users of my application, so therefore I put them in a separate project (which also leads to a separate assembly).
If you have the rare case that you want to test internal methods, you can use InternalsVisibleTo.
If you have the very rare case that you want to test private methods, you can use this technique, as explained by Davy Brion.
I prefer the first approach - separating to unit test to its own project.
placing the unit tests within the test subject will make it dirty. furthermore, you don't necessarily want to distribute your project with the unit tests which will make your dll's bigger and possibly expose things that you don't want to expose to the end user.
most of the open source projects that I saw had a different projects for unit tests.
You shoul place the unit tests in a seperate project.
You should also write them in a way, so that the SUT (System under Test) is not modified in a way to make unittests possible. I mean you should have no helper classes in you main project that exist "only" to support you tests.
Mixing test and production code is allways a bad plan, since you dont want to deliver all that extra code out to your clients. Keep the clear separation that another project offers.
I dont think the "keep the tests quick" argument is a really strong one. Make a clear cut... Testing code does not belong into a production enviroment IMHO...
Edit:
Comment on Edit above:
EDIT: About writing unit-test code with "code under test": Removing the test code from production assembly isn't difficult I guess. Thats what conditional compilation is for. Right?
Yes, it is "easy" to remove the code with a conditional compilation flag, but you wont have tested the final assembly you created, you only tested the assembly you created with the code inside it, then you recompile, creating a new,untested assembly and ship that one. Are you sure all your conditional flags are set 100% correct? I guess not, since you cant run the tests ;)