Friday, 21 October 2011

Moq (Mock) and ToString() weirdness

I came across a bit of weirdness today while trying to add some unit tests to existing code, where ToString() on a mocked (using Moq) object didn't return what I anticipated. Let me demonstrate. First let's create a simple interface and class.
public interface IName
{
}

public class Name : IName
{
  private string _first;
  private string _last;

  public Name(string first, string last)
  {
     _first = first;
     _last = last;
  }

  public override string ToString()
  {
    return _first + " " + _last;
  }
}
So now let's create a little program to test things.
class Program
{
  static void Main(string[] args)
  {
    var name1 = new Name("John", "Doe");
    Console.WriteLine(name1.ToString());   // expected and get "John Doe"

    var name2 = new Mock<IName>();
    name2.Setup(x => x.ToString()).Returns("My Name");  // expect "My Name", but get "Castle.Proxies.INameProxy"

    Console.WriteLine(name2.Object.ToString());
  }
}
As you can see from the comments, my mocked Name object didn't return what I expected. After a little bit of digging, I came to realise that because of the way Mock works, it would only return the correct result if I add the ToString() method to the interface IName, like so.
public interface IName
{
  string ToString();
}
That solves that problem, but, and there's a big but. In my Main method, if I had written
Console.WriteLine(name2.Object); // still gives Castle.Proxies.INameProxy
without the explicit call to ToString() I would still get Castle.Proxies.INameProxy returned even though you could still call the following with the non-mocked name1 object and get "John Doe".
Console.WriteLine(name1.Object); // still gives "John Doe"

Thursday, 6 October 2011

@@IDENTITY, SCOPE_IDENTITY and IDENT_CURRENT, or getting the id of a new record

I have been reminded recently that there is still a need to clarify how one obtains the Id of a recently inserted record on an table with an identity field in SQL Server.

If we take a simple table, created as follows, and add a couple of records
CREATE TABLE Person (
    Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
    Name NVARCHAR(50) NOT NULL
)
GO
INSERT INTO Person(Name) VALUES ('Mary')
INSERT INTO Person(Name) VALUES ('Joe')
we can get back value of the Id field of the latest added record, using three possible methods, shown below.
SELECT @@IDENTITY, SCOPE_IDENTITY(), IDENT_CURRENT('Person')
and in the case above they would all return the expected value 2.

Now, if you created a new connection to the database, and ran the same SELECT query, you'd get the results, NULL, NULL and 2. So here is the first difference, IDENT_CURRENT() returns the latest value of the identity field of the specified table, irrespective of the scope or connection. So if your SELECT isn't in the same transaction as your INSERT, it is possible that IDENT_CURRENT could return the Id of a later record inserted into the same table by a user/application on another connection.

Now, lets create another table called Log, and a (simple) trigger on Person to update the log table whenever an insert is done on the Person table.
CREATE TABLE Log (
    Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
    Message NVARCHAR(50) NOT NULL,
    InsertTime DATETIME NOT NULL
)
GO
CREATE TRIGGER PersonInsertTrigger ON Person
FOR INSERT
AS
   INSERT INTO Log(Message, When) VALUES ('Person Inserted', GETDATE())
GO
So now, when ever one or more records are inserted in to the Person table, a record gets added to the Log table, and note, that the Log table also contains an identity field. If we add another record, and do the same query i.e.
INSERT INTO Person(Name) VALUES ('Ann')
SELECT @@IDENTITY, SCOPE_IDENTITY(), IDENT_CURRENT('Person')
We get the results 1, 3 and 3. Why? Well @@IDENTITY is returning the value of the latest identity field updated irrespective of scope i.e. the value of the identity field from the Log table, not that of the Person table.

The use of @@IDENTITY is still very common, and in many cases will be returning the same value as SCOPE_IDENTITY, but if anyone in the future wants to add a trigger to your table for auditing, or change data capture for data warehousing, it will start returning the wrong value.

In nearly all cases, use SCOPE_IDENTITY().

Thursday, 23 June 2011

Comparing Current and Previous Records in SQL Server

I came across an implmentation of some SQL Server code (T-SQL) that attempted to look at a sequence (datetime) in this case of events and was trying to compare data found in the current record with data found in the previous record in the sequence. The solution used cursors to iterate through the record sets and used variables to store the previous records information so that the appropriate comparisons could be made.  This got me thinking that there must be a set-based solution to this.

First, lets create a problem looking for a solution. We have a number of devices that measure the temperature of a process every hour. We want to produce a query for a period of time that shows the time only when the temperature changes for that device. The example table and data below give a clearer picture.

CREATE TABLE device_recording (
    device_id INT,
    recording_time SMALLDATETIME,
    temperature INT
)
GO
INSERT INTO device_recording VALUES (1, '2011-01-01 09:00', 10)
INSERT INTO device_recording VALUES (1, '2011-01-01 10:00', 10)
INSERT INTO device_recording VALUES (1, '2011-01-01 11:00', 11)
INSERT INTO device_recording VALUES (1, '2011-01-01 12:00', 10)
INSERT INTO device_recording VALUES (1, '2011-01-01 13:00', 10)
INSERT INTO device_recording VALUES (2, '2011-01-01 09:00', 14)
INSERT INTO device_recording VALUES (2, '2011-01-01 10:00', 15)
INSERT INTO device_recording VALUES (2, '2011-01-01 11:00', 15)
INSERT INTO device_recording VALUES (2, '2011-01-01 12:00', 15)
INSERT INTO device_recording VALUES (2, '2011-01-01 13:00', 15)
INSERT INTO device_recording VALUES (3, '2011-01-01 09:00', 8)
INSERT INTO device_recording VALUES (3, '2011-01-01 10:00', 8)
INSERT INTO device_recording VALUES (3, '2011-01-01 11:00', 8)
INSERT INTO device_recording VALUES (3, '2011-01-01 12:00', 8)
INSERT INTO device_recording VALUES (3, '2011-01-01 13:00', 9)

From this we would want a query to produce just the following data.

1, 2011-01-01 09:00, 10
1, 2011-01-01 11:00, 11
1, 2011-01-01 12:00, 10
2, 2011-01-01 09:00, 14
2, 2011-01-01 10:00, 15
3, 2011-01-01 09:00, 8
3, 2011-01-01 13:00, 9

i.e. the time at which the temperature changed for each device.

The way I tackled this was to use a CTE (Common Table Expression), which numbers each row for device ordered by the reading_time. In the example above you want a row number 1,2,...5 for each device, with 1 being against the earliest time, and 5 against the latest time. I make use of the ROW_NUMBER() function and the PARTITION keyword to achieve this.

WITH device_recording_row_num AS
(
    SELECT device_id, recording_time, temperature, 
           ROW_NUMBER() OVER (PARTITION BY device_id ORDER BY recording_time) AS row_num
    FROM device_recording       
)

Now I have a an ordered set of row numbers per device, we can join the table with itself on both the device_id and also the row_num, but with one of the join tables (previous) offset by row_num + 1. At this stage it's probably easier to see in SQL.

WITH device_recording_row_num AS
(
    SELECT device_id, recording_time, temperature, 
           ROW_NUMBER() OVER (PARTITION BY device_id ORDER BY recording_time) AS row_num
    FROM device_recording       
)
SELECT
    [current].device_id, [current].recording_time, [current].temperature
FROM
    device_recording_row_num AS [current]
LEFT OUTER JOIN
    device_recording_row_num AS previous
    ON [current].device_id = previous.device_id
    AND [current].row_num = previous.row_num + 1
WHERE
    [current].temperature <> previous.temperature
    OR [previous].temperature IS NULL
ORDER BY
    [current].device_id, [current].recording_time

Note: I've tested this on SQL Server 2008 but I believe it should work on 2005 too.

This technique could be applied to do other time series related queries.

Thursday, 2 June 2011

Windows 8 Preview - Thoughts from an iPad developer

Yesterday, Microsoft released the video below showing a preview of Windows 8, focussing primarily on the user experience (UX). Without doubt it is impressive, with many of elements having a striking similarity to that of Windows Phone 7.



It's refreshing to see such a departure from the conventional Windows UI, and good to see Microsoft taking some of the ideas from Phone 7 and putting them in their main OS.  It seems a similar trend to Apple in the way features from iOS are creeping in to OSX.

Windows is quite clearly the most important OS for the desktop, the installed base speaks for itself, along with its near complete dominance in the corporate arena. However, as the world continually moves to more web-centric and mobiles apps, Windows 8 will need to work very well on tablet or similarly lower-power (CPU, memory, storage as well as electrical power) devices. If Windows 8 can do this, and performance is good i.e. at least comparable with iOS and the best Android devices, then it puts itself in a very strong position to conquer the tablet market for the business community. The corporate world moves slowly, sometimes years behind the consumer, and for this reason, the battle in the business tablet space is far from over, and possibly yet to really get started.

Senior executives may all be asking for iPads, but corporate IT people still love the policy and central management of Windows devices. Corporates and businesses are full of developers knowledgeable on the technologies that are more likely to make internal app development easier too. One of the joys of developing on iOS is the relatively restricted number of devices you have target and test against. Too many choices in the Windows 8 world could be a problem.

Now here is my real concern, not only have the operating systems got to perform well on a given platform, but the apps have to 'feel' right. Applications developed on tablet devices generally have to be written to take account of the screen size, common actions, gestures, sensible tap target sizes etc. People who use iPads don't just have OSX versions of their apps running on it, they have custom apps written for the device. Windows 8 will be able to run Office - fine on the desktop, but on a slate? Well here comes the conflict. My immediate reaction would be no way - it's too big, you need an alternative stripped down version just for the tablet. This is why Apple has Numbers for OSX and a different, but compatible one for iOS. However, in the business world, thousands of organisations thrive on hundreds of interlinked spreadsheets, databases and reporting systems and applications all built in Excel. Many of which are not edited or only tweaked, and the consumption of this information would still be instantly accessible on a Windows 8 slate. As for creating such spreadsheets, well I don't think they would ever expect you to create them on a slate.

Can Windows 8 be scaled down to run on tablets and more importantly will application developers make the distinction that they may well need an app for tablet Windows 8 and another for desktop Windows 8, or at least be prepared to created two user experiences. To me, it initially seemed very interesting that Windows Phone 7 wasn't being scaled up, rather than Windows 8 being scaled down, until I thought about Office, and remembered how much of a lifeblood this application is both to the business world and Microsoft's revenue stream.

At the end of the day, most people don't care about the operating system, they care about the applications that run on them. Having great apps on specific devices will require compromises, and that may well be having to write two versions of an app. Microsoft may have already lost out in the consumer market, but I certainly would not write them off in the business world.

Thursday, 28 April 2011

Code Coverage in XCode 4

Code coverage is an important part of testing your application. In my opinion unit testing and code coverage have very much been given a back seat in iOS development. Even with XCode 4, unit testing is nothing like as smoothly integrated as in IDEs such as IntelliJ or Visual Studio.

In order to ensure that your tests are fully exercising your code, running a coverage tool is useful to show you what lines in your code do not get called by your tests.

Setting up code coverage in XCode 4, is less than obvious.  Also, before starting I recommend downloading CoverStory from Google Code, which is a simple UI for viewing code coverage.

To demonstrate how to get code coverage working in the simplest case, let's create a standard View based application, which I will call CodeCover, and for now just to keep it simple I won't check the option for Unit Tests just to keep us focused on one thing at a time. (I'm using XCode 4, with iOS SDK 4.3.)

Code coverage data is obtained by using the Gnu gcov tool, in conjunction with the GCC compliler.

First we need to change a few settings in the build to link in the gcov library, and turn on code coverage. In the build settings, under Linking, add the -lgcov to "Other Linker Flags". Then under the Code Generation section change "Instrument Program Flow" to Yes.

You then need to change the compiler version to GCC 4.2, not LLVM GCC 4.2.

And finally look for the Prefix Header option and remove what is in there, in my case it was CodeCover/CodeCover-Prefix.pch - make sure this is the one shown in the Target build settings, not the project settings.

Now build and run your application in the Simulator. When finished quit the Simulator - this is very important as this terminates your app correctly and it is at this point that the output files used for analysis are generated. Pressing the home button on the simulated app does not do the same thing.

You now need to locate the output files. These are located deep in the Build folder (which in XCode 4 by default will be something like ~/Library/Developer/XCode/DerivedData/CodeCover.../Build)
and under that will be Intermediates/CoverCode.build/Debug-iphonesimulator/CodeCover.build and finally you get to the Objects-normal folder. If you look in here you should see a bunch of gcda and gcno files.

Whilst you can use gcov to examine the files, I would use CoverStory to open the Objects-normal folder. If all goes well you should see your code coverage information. Note: typically the code coverage files (.gcda files) are found in the i386 folder under Objects-normal. CoverStory though searches this folder for you.

Some points to note. The steps above are the minimum I found to get code coverage to work. In practice you would almost certainly want to do this in conjunction with unit tests so you would also want to turn on the compiler option "Generate Test Coverage Files".

If you don't want to keep quitting the Simulator to make your app terminate, then it is possible to add the "Application does not run in background" set to YES into your info.plist to ensure your app terminates when the home button is pressed. However, you may well want to actually test what is going on in the background. Also remember to remove it when you are finished.

Sunday, 24 April 2011

Version Control (a few years on)

Two separate, but related events this week have provoked me in to this post. It's the old chestnut of version control.  A few years ago I wrote a post on version control and how important it was. At the time I was staggered to find it was not being used as much as it should have been. So here we are several years later and I'm pleased to observe a big increase in the number of people using it, both in a commercial environment and also for personal projects.  It is this last use-case that I am really pleased about. Version control should be used by everybody's development projects, and not just in team environments.

I am now a complete convert to distributed version control systems having used Mercurial and Git for the last three years. Even for individuals their ease of use for branching and merging makes them an invaluable tool. However, I recently moved from Mercurial to Git. I really like the two systems and I still think Mercurial is easier to get going with, however my system of choice now is Git, and it's all because of GitHub. For those that don't know, very basically GitHub is hosted Git, but that simply doesn't do it justice - it's a fabulously richly featured facility and I would encourage everyone to sign up and try it out. It is in my opinion on of the key reasons why more and more individuals are using version control for their own projects.

So in summary

  1. use version control
  2. use it even if you are not operating in a team
  3. use it for things other than just code, e.g. database scripts
  4. try a DVCS system, if you haven't already done so
  5. give yourself time to get your head around it
  6. sign up and give GitHub a go 

Monday, 4 April 2011

A Bit of Love and Respect

Today, there are very few development projects that require a single skilled individual. Teams have developers, designers, DBAs, testers, managers etc. All too often though, these individuals are kept in their own worlds, and sometimes their own offices. Huge amounts of time is wasted because they don't really understand what each other does and how they can all be mutually beneficial.  Success doesn't come from a developer throwing his rough site over the office partition to a designer and saying "make it pretty now". Good database administrators often have a much deeper understanding of what SQL comes out of frameworks such as Hibernate or Entity Framework than a developer, and can help them make more efficient code.

The same goes for management too. Giving others an insight into their decision making process will give lead to a better understanding of the business issues at hand, and that decisions aren't simply made because you are the boss. Similarly, a manager is likely to gain a deeper understanding into your work and how and why things take as long as they do. Managers need to allow time for, and encourage working together across disciplines and view it as time well spent. In the long run it is very cost effective since it massively reduces rework. Treat each other with respect and not as though they have some ulterior motive to take over your job or put a spanner in the works.

The idea is to ship great products and services in a timely fashion, and working together, embracing each other's skills will be a good step in the right direction.