I'm having trouble unit testing a method that changes some properties of a reference type that is passed to it.
As an example, let's say I have a class called Policy.
Policy policy = new Policy();
policy.Status = Active;
I then pass this policy to the policy manager in order to inactivate the policy.
policyManager.InactivatePolicy(policy);
The inactivate policy method does the following:
public void InactivatePolicy(Policy policy)
{
policy.Status = Inactive;
UpdatePolicy(policy); //saves the updated policy details via nhibernate
}
What I'm having trouble with is unit testing this DoSomething method. (ignore the fact that what it does in this example is useless)
public void DoSomething(Policy policy)
{
Policy policy = new Policy();
policy.Status = Active;
policyManager.InactivatePolicy(policy);
}
Because I mock out policy Manager, the status does not get set to inactive and as a result when I assert that after DoSomething is called the status of the policy is inactive I get a test failure since it is still Active.
[Test]
public void TheStatusShouldBeInactiveWhenWeDoSomething()
{
Mock<IPolicyManager> policyManagerMock = new Mock<PolicyManager>();
MyClass mc = new MyClass(policyManagerMock.Object);
Policy policy = new Policy();
policy.Status = Active;
mc.DoSomething(policy);
Assert.That(policy.Status, Is.EqualTo(Inactive)); //this fails
}
So I'm in a situation where the code works in reality but just not when isolated in my unit tests.
The only way I've been able to work around this issue is to have the policy manager's InactivatePolicy method return the modified policy so that I can mock up the expected return value.
public Policy InactivatePolicy(Policy policy)
{
policy.Status = Inactive;
UpdatePolicy(policy); //saves the updated policy details via nhibernate
return policy;
}
[Test]
public void TheStatusShouldBeInactiveWhenWeDoSomething()
{
Mock<IPolicyManager> policyManagerMock = new Mock<PolicyManager>();
MyClass mc = new MyClass(policyManagerMock.Object);
Policy expectedInactivePolicy = new Policy();
expectedInactivePolicy.Status = Inactive;
Policy policy = new Policy();
policy.Status = Active;
policyManagerMock
.Setup(p => p.InactivatePolicy(policy))
.Returns(expectedInactivePolicy);
mc.DoSomething(policy);
Assert.That(policy.Status, Is.EqualTo(Inactive)); //this now succeeds
}
Typically when I'm struggling to unit test something it's an indication I'm doing things wrong.
Does anyone know if this there is a better way to do this? Is one essentially forced to return values which were originally intended to have been updated via the reference value that was passed into the method?
Is my problem possibly that the policy manager shouldn't have an InactivatePolicy method but it should instead be on the Policy object itself and the database update called later?