Latest Release: Sample Northwind.Web Issues

Aug 5, 2014 at 2:26 AM
Hi all,

I've just downloaded the latest release today and I seem to be having a couple of problems with missing references and code errors in the Northwind.Web project only. I have been using earlier v3 releases which were fine.
  1. The reference to Microsoft.Practices.ObjectBuilder2 is missing, there is a warning symbol next to this reference dll. Is this even required?
  2. Under API and in CustomerController.cs I have many errors related to "Cannot resolve missing symbol 'BadRequest' and 'NotFound' and 'Conflict' and 'StatusCode' etc throughout the various methods.
So it seems something has gone astray. Nuget during 'Rebuild' downloaded missing packages to no avail. Can anyone help and point me in the right direction?

Many thanks

Paul
Aug 6, 2014 at 12:10 AM
Well not sure what happened but after reopening the sample project a few times over the past few days all is now well..... go figure :-/
Marked as answer by DotNetRules on 8/5/2014 at 5:11 PM
Sep 21, 2014 at 5:03 PM
In running the project I found a particular process was needed to get everything working. Here's what I did.
  1. Open the Sample Northwind.sln and build the project. This will install the correct packages from nuget. Under the sample solution in the .nugget/NuGet.targets you'll see all the installation and references being pulled in.
  2. Next, I ran the Northwind.test, for a sanity check of course. It failed. There is a README.txt under the project. Copy the instnwnd.sql to c:\temp directory. This is used to create a new database using Sql. If you don't have a database installed, you'll need to for this to work.
  3. In the Northwind.test project's App.config change the connection string to give the project SA access to the database. Since you'll be creating a database from the code, it needs access to Master.
  4. For the integration test I had to make some minor code modification for its all to work. You need to add a CheckIfDatabaseExist method. If not the code is attempting to drop and recreate the NorthwindTest database several times.
    private static bool CheckIfDatabaseExists()
    {
        var cmdText = string.Format("SELECT database_id FROM sys.databases WHERE Name = '{0}'", "NorthwindTest");
    
        var bRet = false;
        using (var connection = new SqlConnection(MasterConnectionString))
        {
            connection.Open();
            using (var sqlCmd = new SqlCommand(cmdText, connection))
            {
                var nRet = (int)sqlCmd.ExecuteScalar();
    
                bRet = nRet > 0;
            }
        }
    
        return bRet;
    }
    
  5. Modify the SettingUpNorthwindTestDatabase method to by-pass the database creation if it already exists

    [TestInitialize]
    public void SettingUpNorthwindTestDatabase()
    {
        if (CheckIfDatabaseExists()) return;
    
        TestContext.WriteLine("Please ensure Northwind.Test/Sql/instnwnd.sql is copied to C:\\temp\\instnwnd.sql for test to run succesfully");
        TestContext.WriteLine("Please verify the the Northwind.Test/app.config connection strings are correct for your environment");
    
        TestContext.WriteLine("TestFixture executing, creating NorthwindTest Db for integration  tests");
        TestContext.WriteLine("Loading and parsing create NorthwindTest database Sql script");
    
        var file = new FileInfo("C:\\temp\\instnwnd.sql");
        var script = file.OpenText().ReadToEnd();
        RunSqlOnMaster(script);
        TestContext.WriteLine("NorthwindTest Db created for integration tests");
    }
    
  6. Avoid any unique constraints on inserting new customers. In the Northwind.Test.IntegrationTests.CustomerRepositoryTests add a private property
private string CustomerId { get; set; }. This will be used for the integration testing.
  1. Modify the following methods CreateCustomerTest and CreateAndUpdateAndDeleteCustomerGraphTest
    Insert the following line CustomerId = Guid.NewGuid().ToString().Remove(5);
    Next replace all the CustomerID = CustomerId, //"LLE37",
var customer = customerRepository.Find(CustomerId); //("LLE37");
            Assert.AreEqual(customer.CustomerID, CustomerId); //"LLE37"); 
The same for the CreateAndUpdateAndDeleteCustomerGraphTest method
  1. Lastly do the same with the Northwind.Test.IntegrationTests.UnitOfWork_Tests. Update the customer ids in the UnitOfWork_Transaction_Test method.

    var customerId1 = Guid.NewGuid().ToString().Remove(5);
    var customerId2 = Guid.NewGuid().ToString().Remove(5);

    customerService.Insert(new Customer { CustomerID = customerId1, CompanyName = "SkyRanch", ObjectState = ObjectState.Added });
    customerService.Insert(new Customer { CustomerID = customerId2, CompanyName = "SkyRanch", ObjectState = ObjectState.Added });

    var customer = customerService.Find(customerId1);
    Assert.AreSame(customer.CustomerID, customerId1);

    customer = customerService.Find(customerId2);
    Assert.AreSame(customer.CustomerID, customerId2);
At this point the project should compile, build and testing should all work.

Good Luck
Coordinator
Sep 21, 2014 at 8:43 PM
The database creation needs to execute, rebuild the database, and reseed the data each and every time so that schema and data is guaranteed to be in specific state for each integration test sets. Meaning CustomerRepositoryTests and ProductRepositoryTest should not impact each other in anyway.
Sep 21, 2014 at 9:55 PM
Edited Sep 21, 2014 at 10:19 PM
Thank you for the response.

I believe we'd agree that the state of the data should remain consistent for a repeatable test.

Two conclusions I drew, invocation of the integration methods retained a connection thus drawing an error not allowing the database to be dropped (error generated – “cannot drop database because it is currently in use”). If the goal is data integrity then it seems awfully expensive and time consuming to drop and recreate databases. Simply, cleaning up after oneself then starting a new is reasonable from a testability stand point. I guess my point is mainly the ladder. However, I think if this is the goal, then it would seem reasonable to write a stored procedure to clean the data, reset the identity keys and start anew. Maybe for readers of this information this is a good point to understand about the integration testing.

Once again, thank you for clarifying the reasoning behind the operations.
Coordinator
Sep 22, 2014 at 5:52 AM
Edited Sep 22, 2014 at 5:53 AM
  1. We haven't had any issues of "cannot drop database because it's currently in use", however that doesn't mean that this isn't happening, we'll look into this and see if we can reproduce this issue.
  2. Integration Tests to this degree (resetting the schema and reseeding the database) e.g. (as you've mentioned: data should remain consistent for a repeatable test), isn't common. We went to the extra mile since this framework is a repository framework, again in this case, integration test to the degree of rebuilding and reseeding the database was deemed essential. So this was our first pass, we'll look into the performance of the integration test, specifically reseeding the data vs. rebuilding the database. Note: Integration test, unlike unit tests are more for daily runs, daily commits, etc. vs. every local compile, this was also considered when we implemented these integration tests.
Thank you for the great feedback.
Marked as answer by lelong37 on 9/21/2014 at 10:53 PM