views:

107

answers:

2

After some digging here, I took the advice in this thread: http://stackoverflow.com/questions/371961/how-to-unit-test-c-web-service-with-visual-studio-2008

I've created a separate class and my web service class is just a wrapper for that one. The problem is that when I try to create a unit test project in VS2008, it insists on creating a unit test that acts like I'm testing the web service calls instead of the class I specified. I can't get to the class I'm trying to test.

I have a web service "subscription_api.asmx". The code behind is "subscription_api.cs" which contains the web method wrapper calls to the real code at "subscription.cs".

I would expect to be able to do the following:

[TestMethod()]
        public void GetSystemStatusTest()
        {
            subscription sub = new subscription();
            XmlNode node = sub.GetSystemStatusTest();
            Assert.IsNotNull(node);
        }

But instead I get this mess which is autogenerated from VS'08:

/// <summary>
        ///A test for GetSystemStatus
        ///</summary>
        // TODO: Ensure that the UrlToTest attribute specifies a URL to an ASP.NET page (for example,
        // http://.../Default.aspx). This is necessary for the unit test to be executed on the web server,
        // whether you are testing a page, web service, or a WCF service.
        [TestMethod()]
        [HostType("ASP.NET")]
        [AspNetDevelopmentServerHost("C:\\CVSROOT\\rnr\\pro\\product\\wms\\ss\\subscription_api", "/subscription_api")]
        [UrlToTest("http://localhost/subscription_api")]
        public void GetSystemStatusTest()
        {
            subscription_Accessor target = new subscription_Accessor(); // TODO: Initialize to an appropriate value
            XmlNode expected = null; // TODO: Initialize to an appropriate value
            XmlNode actual;
            actual = target.GetSystemStatus();
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

Additionally, there is a "subscription_api.accessor" in the Test References folder.

When I try this:

[TestMethod()]
public void GetSystemStatusTest2()
{
    subscription_Accessor sub = new subscription_Accessor();
    XmlNode node = sub.GetSystemStatus();
    Assert.IsNotNull(node);
}

I get an error:

Test method subscription_api.Test.subscriptionTest.GetSystemStatusTest2 threw exception:  System.TypeInitializationException: The type initializer for 'subscription_Accessor' threw an exception. --->  System.ArgumentNullException: Value cannot be null.

I'm really new to unit testing and feel lost. How can I create a unit test just for my subscription class in "subscription.cs" without testing the web service? Am I limited to testing within the same project (I hope not)? Do I have to put the target class in its own project outside of the web service project?

+1  A: 

It sounds like your web service was created in a "web site" project instead of a "web application" project. The problem is that web sites are not built to a single DLL that you can reference, as web projects are.

If this is the case and you are using a web site type project, then you'll need to convert it to a web application project to take advantage of unit testing the code directly. There are many blog posts out there on how to convert your project, just search for "convert asp.net web site to web application".

Alternatively / additionally, you may want to move this code to it's own class library and reference that library in the project that contains your web service.

Jeff Schumacher
OK, thanks for the info. One thing I forgot to mention was that this project was converted from VS'05 to VS'08 for the express purpose of making it testable.
Dan Bailiff
That did the trick. VS'08 still wants to create web service tests when I try to autogenerate the unit tests, but I can create the tests I want by hand and they behave as expected.
Dan Bailiff
Awesome. Personally, I wish they would remove web site type projects from VS all together. ;)Glad I could help.
Jeff Schumacher
A: 

To test a WCF service in a website project, you can also add the service to your test project with "Add service reference". As URL, enter the http://localhost:4324/...?wsdl url.

Now you can write a test method:

[TestClass()]
public class MyServiceTest
{
    #region -- Webservice initialisation

    // The client object for the WCF service.
    private static MyServiceNamespace.MyServiceClient _service;

    [ClassInitialize]
    public static void InitializeClass(TestContext ctx)
    {
        _service = new MyServiceNamespace.MyServiceClient();
    }

    [ClassCleanup]
    public static void CleanupClass()
    {
        _service.Close();
    }

    #endregion


    // An example test
    [TestMethod()]
    public void GetBlaBlaTest()
    {
        var actual = _service.GetBlaBla();
        Assert.IsTrue(actual.Status.IsSuccess, "Call should return success status");
        Assert.AreEqual("blabla", actual.Result, "Call should return the string 'blabla'");
    }
}

When the project is started, both the unit test application and website project will start, and the tests will be running against the ASP.NET Development server. This has the advantage any initialization code will also run properly, simulating real-life use of the service.

vdboor