I've just finished reading "Professional Test-Driven Development with C#" and have been trying to find a way to achieve 100% coverage in my code. It's all good until I hit a repository class that is filled with methods implemented something like this:
public IEnumerable<MyDataContract> LoadConditional(bool isCondition)
{
const string QUERY = #"SELECT ...fields... FROM MyData WHERE [IsCondition] = #IsCondition";
return DataAccessor.ReadMyContracts(QUERY, isCondition); // something, something...
}
I've been thinking about this for some time, and have not been able to find an answer on the internet that answers this question directly.
I read things that would suggest that SQL related business would exist in another assembly. I don't require this though and don't believe I should have to go there. And this, from a code coverage, perspective is a pretty superficial change.
I've read that you can hook up databases for your unit tests (which I've done before). But this just well... I dunno, it doesn't feel right. The tests are slow and have a significant increase in maintenance.
My gut feeling is that without the last bit I mentioned, this method can't be unit tested. How should I be viewing this problem?
First let me say that I believe that achieving 100% coverage makes no sense at all and doesn't prove anything.
That being said, I typically use some layer between DB and business logic - some simple mapper (PetaPoco, Dapper, OrmLite) or, rarely, a full blown ORM (NHibernate).
In cases where I need integration tests against a DB, these tools allow me to run the same queries against a test DB (e.g. an in-memory SQLite DB) instead of 'real' DB server.
With regard to your concern that "the tests are slow and have a significant increase in maintenance." you should bear in mind that these are not unit tests anymore - these are integration tests and they can't be as fast as unit tests.
The way I see it, if you do actual data access, you are going in to integration testing and leaving the realm of unit testing. I personaly prefer to keep SQL inside the data access layer only, i.e. a single layer before the DB itself and then I test everything up to that point. In my view a method named ReadMyContracts should already have the correct SQL for accessing the data and should only receive (and pass on) the isCondition parameter.
That`s just MHO.
Related
I know that in TDD, you should avoid writing code that is not tested beforehand, but I'm wondering if this is one of those times where the rule might be broken for the sake of simplicity (avoiding testing of wrappers for third party libraries for testing purposes, like the gateway pattern for instance). I'm currently testing them though, something like this:
[TestMethod]
public void CreateShouldReturnANewInstance()
{
var tcpClientMock = new Mock<ITcpClient>();
var spooler2 = OutboundMessageSpooler.Create(tcpClientMock.Object);
Assert.IsTrue(spooler2 != null && spooler2 is OutboundMessageSpooler);
}
The test you've written strikes me as a good test, but not a very important one. There is this bit of functionality which creates a spooler from a TCP client, and this test demonstrates that that unit of functionality works. That's a good way to drive that bit of functionality - it didn't work before, you demonstrated with a red test, you wrote the method, and now it works. Cool. Necessary? Probably not. Helpful for regression? Again, probably not. Helpful as a model for tests of future, perhaps more complex, logic? Maybe.
I wouldn't advise you against writing tests like these - after all, they're pretty easy to write and may help you think about how you want the feature implemented - what TDD is really all about - but I probably wouldn't urge you to write them, either. See how helpful you find it, and if the answer is "not much," spend your test-driving resources elsewhere.
I have one class which talks to DataBase.
I have my integration-tests which talks to Db and asserts relevant changes. But I want those tests to be ignored when I commit my code because I do not want them to be called automatically later on.
(Just for development time I use them for now)
When I put [Ignore] attribute they are not called but code-coverage reduces dramatically.
Is there a way to keep those tests but not have them run automatically
on the build machine in a way that the fact that they are ignored does
not influence code-coverage percentage?
Whatever code coverage tool you use most likely has some kind of CoverageIgnoreAttribute or something along those lines (at least the ones I've used do) so you just place that on the method block that gets called from those unit tests and you should be fine.
What you request seems not to make sense. Code-Coverage is measured by executing your tests and log which statements/conditions etc. are executed. If you disable your tests, nothing get executed and your code-coverage goes down.
TestNG has groups so you can specify to only run some groups, automatically and have the others for usage outside of that. You didn't specify your unit testing framework but it might have something similar.
I do not know if this is applicable to your situation. But spontaneously I am thinking of a setup where you have two solution files (.sln), one with unit/integration tests and one without. The two solutions share the same code and project files with the exception that your development/testing solution includes your unit tests (which are built and run at compile time), and the other solution doesn't. Both solutions should be under source control but only the one without unit tests are built by the build server.
This kind of setup should not need you to change existing code (too much). Which I would prefer over rewriting code to fit your test setup.
First, I apologize if this is not an appropriate venue to ask this question, but I wasn't really sure where else to get input from.
I have created an early version of a .NET object persistence library. Its features are:
A very simple interface for persistence of POCOs.
The main thing: support for just about every conceivable storage medium. This would be everything from plain text files on the local filesystem, to embedded systems like SQLite, any standard SQL server (MySQL, postgres, Oracle, SQL Server, whatever), to various NoSQL databases (Mongo, Couch, Redis, whatever). Drivers could be written for nearly anything, so for instance you could fairly easily write a driver where the actual backing store could be a web-service.
When I first had this idea I was convinced it was totally awesome. I quickly created an initial prototype. Now, I'm at the 'hard part' where I am debating issues like connection pooling, thread safety, and debating whether to try to support IQueryable for LINQ, etc. And I'm taking a harder look at whether it is worthwhile to develop this library beyond my own requirements for it.
Here is a basic example of usage:
var to1 = new TestObject { id = "fignewton", number = 100, FruitType = FruitType.Apple };
ObjectStore db = new SQLiteObjectStore("d:/objstore.sqlite");
db.Write(to1);
var readback = db.Read<TestObject>("fignewton");
var readmultiple = db.ReadObjects<TestObject>(collectionOfKeys);
The querying interface that works right now looks like:
var appleQuery = new Query<TestObject>().Eq("FruitType", FruitType.Apple).Gt("number",50);
var results = db.Find<TestObject>(appleQuery);
I am also working on an alternative query interface that lets you just pass in something very like a SQL WHERE clause. And obviously, in the NET world it would be great to support IQueryable / expression trees.
Because the library supports many storage mediums with disparate capabilities, it uses attributes to help the system make the best use of each driver.
[TableName("AttributeTest")]
[CompositeIndex("AutoProperty","CreatedOn")]
public class ComplexTypesObject
{
[Id]
public string id;
[QueryableIndexed]
public FruitType FruitType;
public SimpleTypesObject EmbeddedObject;
public string[] Array;
public int AutoProperty { get; set; }
public DateTime CreatedOn = DateTime.Now;
}
All of the attributes are optional, and are basically all about performance. In a simple case you don't need any of them.
In a SQL environment, the system will by default take care of creating tables and indexes for you, though there is a DbaSafe option that will prevent the system from executing DDLs.
It is also fun to be able to migrate your data from, say, a SQL engine to MongoDB in one line of code. Or to a zip file. And back again.
OK, The Question:
The root question is "Is this useful?" Is it worth taking the time to really polish, make thread-safe or connection pooled, write a better query interface, and upload somewhere?
Is there another library already out there that already does something like this, NAMELY, providing a single interface that works across multiple data sources (beyond just different varieties of SQL)?
Is it solving a problem that needs to be solved, or has someone else already solved it better?
If I proceed, how do you go about trying to make your project visible?
Obviously this isn't a replacement for ORMs (and it can co-exist with ORMs, and coexist with your traditional SQL server). I guess its main use cases are for simple persistence where an ORM is overkill, or for NoSQL type scenarios and where a document-store type interface is preferable.
My advice: Write it for your own requirements and then open-source it. You'll soon find out if there's a market for it. And, as a bonus, you'll find that other people will tell you which bits need polishing; there's a very high chance they'll polish it for you.
Ben, I think it's awesome. At the very least post it to CodePlex and share with the rest of the world. I'm quite sure there are developers out there who can use an object persistence framework (or help polish it up).
For what its worth I think its a great idea.
But more importantly, you've chosen a project (in my opinion) that will undoubtedly improve your code construction and design chops. It is often quite difficult to find projects that both add value while improving your skills.
At least complete it to your initial requirents and then open source it. Anything after that it is a bonus!
While I think the idea is intriguing, and could be useful, I am not sure what long-term value it may hold. Given the considerable advances with EF v4 recently, including things like Code-Only, true POCO support, etc. achieving what you are talking about is actually not that difficult with EF. I am a true believer in Code-Only these days, as it is simple, powerful, and best of all, compile-time checked.
The idea about supporting any kind of data store is intriguing, and something that is worth looking into. However, I think it might be more useful, and reach a considerably broader audience, if you implemented store providers for EF v4, rather than trying to reinvent the wheel that Microsoft has now spent years on. Small projects more often than not grow...and things like pooling, thread safety, LINQ/IQueryable support, etc. become more important...little by little, over time.
By developing EF data store providers for things like SqLite, MongoDB, Xml files or flat files, etc. you add to the capabilities of an existing, familiar, accessible framework, without requiring people to learn an additional one.
Omar Al Zabir is looking for "a simpler way to do AOP style coding".
He created a framework called AspectF, which is "a fluent and simple way to add Aspects to your code".
It is not true AOP, because it doesn't do any compile time or runtime weaving, but does it accomplish the same goals as AOP?
Here's an example of AspectF usage:
public void InsertCustomerTheEasyWay(string firstName, string lastName, int age,
Dictionary<string, string> attributes)
{
AspectF.Define
.Log(Logger.Writer, "Inserting customer the easy way")
.HowLong(Logger.Writer, "Starting customer insert", "Inserted customer in {1} seconds")
.Retry()
.Do(() =>
{
CustomerData data = new CustomerData();
data.Insert(firstName, lastName, age, attributes);
});
}
Here are some posts by the author that further clarify the aim of AspectF:
AspectF fluent way to put Aspects into your code for separation of concern (Blog)
AspectF (google code)
AspectF Fluent Way to Add Aspects for Cleaner Maintainable Code (CodeProject)
According to the author, I gather that AspectF is not designed so much as an AOP replacement, but a way to achieve "separation of concern and keep code nice and clean".
Some thoughts/questions:
Any thoughts on using this style of coding as project grows?
Is it a scalable architecture?
performance concerns?
How does maintainability compare against a true AOP solution?
I don't mean to bash the project, but
IMHO this is abusing AOP. Aspects are not suitable for everything, and used like this it only hampers readability.
Moreover, I think this misses one of the main points of AOP, which is being able to add/remove/redefine aspects without touching the underlying code.
Aspects should be defined outside of the affected code in order to make them truly cross-cutting concerns. In AspectF's case, the aspects are embedded in the affected code, which violates SoC/SRP.
Performance-wise there is no penalty (or it's negligible) because there is no runtime IL manipulation, just as explained in the codeproject article. However, I've never had any perf problems with Castle DynamicProxy.
On a recent project, it was recommended to me that I give AspectF a try.
I took to heart the idea of laying all the concerns up front, and having the code that does the real work blissfully unaware of all the checks and balances that happened outside of it.
I actually took it a little further, and added a security "concern" that required credentials that were being received as part of a WCF request. It went off to the database and did what it had to. I did obvious validations, and the security check before running the actual code that would return the required data.
I found this approach quite a refreshing change, and I certainly liked that I had the source of AspectF to walk through as I was debugging and testing the service calls.
In the office, some argued that these concerns should be implemented as a decoration on a class / method. But it doesn't really matter where you decorate it, at some point somewhere, you need to say you wish to perform certain actions / checks. I like the fact that it's all laid out in-place, not as another code file, not as some kind of configuration file, and for once, not adding yet another decoration to a class / method.
I'm not saying it's true AOP - and I certainly think there are solutions and situations where it really isn't the best way of implementing your objectives, but given that it's just a couple of K of source files, that makes for a very light-weight implementation.
AspectF is basically a very clever way of chaining delegates together.
I don't think every developer is going to look at the code and say how wonderful it is to look at, indeed in our office it confused some of us! But once you understand what's going on, it's an inexpensive way of achieving much of what can be done by other approaches too.
So I'm working on some legacy code that's heavy on the manual database operations. I'm trying to maintain some semblance of quality here, so I'm going TDD as much as possible.
The code I'm working on needs to populate, let's say a List<Foo> from a DataReader that returns all the fields required for a functioning Foo. However, if I want to verify that the code in fact returns one list item per one database row, I'm writing test code that looks something like this:
Expect.Call(reader.Read()).Return(true);
Expect.Call(reader["foo_id"]).Return((long) 1);
// ....
Expect.Call(reader.Read()).Return(true);
Expect.Call(reader["foo_id"]).Return((long) 2);
// ....
Expect.Call(reader.Read()).Return(false);
Which is rather tedious and rather easily broken, too.
How should I be approaching this issue so that the result won't be a huge mess of brittle tests?
Btw I'm currently using Rhino.Mocks for this, but I can change it if the result is convincing enough. Just as long as the alternative isn't TypeMock, because their EULA was a bit too scary for my tastes last I checked.
Edit: I'm also currently limited to C# 2.
To make this less tedious, you will need to encapsulate/refactor the mapping between the DataReader and the Object you hold in the list. There is quite of few steps to encapsulate that logic out. If that is the road you want to take, I can post code for you. I am just not sure how practical it would be to post the code here on StackOverflow, but I can give it a shot to keep it concise and to the point. Otherwise, you are stuck with the tedious task of repeating each expectation on the index accessor for the reader. The encapsulation process will also get rid of the strings and make those strings more reusable through your tests.
Also, I am not sure at this point how much you want to make the existing code more testable. Since this is legacy code that wasn't built with testing in mind.
I thought about posting some code and then I remembered about JP Boodhoo's Nothin But .NET course. He has a sample project that he is sharing that was created during one of his classes. The project is hosted on Google Code and it is a nice resource. I am sure it has some nice tips for you to use and give you ideas on how to refactor the mapping. The whole project was built with TDD.
You can put the Foo instances in a list and compare the objects with what you read:
var arrFoos = new Foos[]{...}; // what you expect
var expectedFoos = new List<Foo>(arrFoos); // make a list from the hardcoded array of expected Foos
var readerResult = ReadEntireList(reader); // read everything from reader and put in List<Foo>
Expect.ContainSameFoos(expectedFoos, readerResult); // compare the two lists
Kokos,
Couple of things wrong there. First, doing it that way means I have to construct the Foos first, then feed their values to the mock reader which does nothing to reduce the amount of code I'm writing. Second, if the values pass through the reader, the Foos won't be the same Foos (reference equality). They might be equal, but even that's assuming too much of the Foo class that I don't dare touch at this point.
Just to clarify, you want to be able to test your call into SQL Server returned some data, or that if you had some data you could map it back into the model?
If you want to test your call into SQL returned some data checkout my answer found here
#Toran: What I'm testing is the programmatic mapping from data returned from the database to quote-unquote domain model. Hence I want to mock out the database connection. For the other kind of test, I'd go for all-out integration testing.
#Dale: I guess you nailed it pretty well there, and I was afraid that might be the case. If you've got pointers to any articles or suchlike where someone has done the dirty job and decomposed it into more easily digestible steps, I'd appreciate it. Code samples wouldn't hurt either. I do have a clue on how to approach that problem, but before I actually dare do that, I'm going to need to get other things done, and if testing that will require tedious mocking, then that's what I'll do.