tags:

views:

555

answers:

2

I have a method that sets a property

public void SetNetworkCredential(string userName, string password, string domain)
{
    _reportExecutionService.Credentials = new NetworkCredential(userName, password, domain);
}

how do I verify that Credentials was called with a valid NetworkCredential?

I tried this TestMethod but it fails because the NetworkCredential objects are different references

[TestMethod]
public void TestTest()
{
    const string userName = "userName";
    const string password = "password";
    const string domain = "domain";

    var mock = MockRepository.GenerateMock<IReportExecutionService>();
    var rptService= new ReportService(mock);

    rptService.SetNetworkCredential(userName, password, domain);

    mock.AssertWasCalled(x => x.Credentials = new System.Net.NetworkCredential(userName, password, domain));
}

Is there a way to validate that the setter was called with an object of type NetworkCredential and with the correct parameters?

+2  A: 

Edit: Rethinking this problem, my previous suggested answer would probably not work. Here's why:

Essentially, you are attempting to verify that the dependency of a dependency has been set up correctly. That is probably why you are having problems writing a unit test for this. You probably want to consider whether it would make sense for you to move the SetNetworkCredential method into the class that implements IReportExecutionService instead.

And if you do, the unit test for that method would be simple enough:

[Test]
public void TestSetNetworkCredential()
{
    const string userName = "userName";
    const string password = "password";
    const string domain = "domain";

    var rptService= new ReportExecutionService();

    rptService.SetNetworkCredential(userName, password, domain);
    Assert.AreEqual(userName, rptService.Credentials.UserName);
    Assert.AreEqual(password, rptService.Credentials.Password);
    Assert.AreEqual(domain, rptService.Credentials.Domain);
}
jpoh
That would be ideal for sure. But the class that implements IReportExecutionService is a code generated class (WSDL to SSRS), I extracted the IReportExecutionService so that I could mock it.
Jon Erickson
+6  A: 

I fixed it by making the ReportService accept a Network Credential instead of the username, password, domain

public void SetNetworkCredential(NetworkCredential networkCredential)
{
    _reportExecutionService.Credentials = networkCredential;
}

so my test was much easier

[TestMethod]
public void TestTest()
{
    const string userName = "userName";
    const string password = "password";
    const string domain = "domain";

    var mock = MockRepository.GenerateMock<IReportExecutionService>();
    var rptService= new ReportService(mock);

    var networkCredential = new System.Net.NetworkCredential(userName, password, domain);

    rptService.SetNetworkCredential(networkCredential);

    mock.AssertWasCalled(x => x.Credentials = networkCredential);
}
Jon Erickson
Excellent answer, so this code actually works it tests if setter was called with given value: mock.AssertWasCalled(x => x.PropertyName = VALUE_WE_ARE_CHECKING);
Roboblob