fhnaseer
fhnaseer

Reputation: 7277

How to check setter is not called for a moq object

I have a property. In my unit-test I want to make sure that set is not called. How I can achieve this?

I have able to check that value is set, but how can I make sure that it is not set.

public ISomeInterface
{
    bool? SomeProperty { get; set; }
}


public SomeClass
{
    SomeClass(ISomeInterface someInterface)
    {    _someInterface = someInterface;    }

    public void SomeMethod(bool condition)
    {
         if (condition)
              _someInterface.SomeProperty = true;
    }
}

// Test
var moq = new Mock<ISomeInterface>();
var target = new SomeClass(moq.Object);

target.SomeMethod(false);

// Check here that someInterface.SomeProperty set is not called.
moq.VerifySet(i => i.SomePropery = true); // This checks that set is called. But how to check if it is not called?

Upvotes: 0

Views: 698

Answers (2)

Calling .VerifyAll() may also be helpful :D

Upvotes: 0

Stephen Byrne
Stephen Byrne

Reputation: 7485

moq.VerifySet(i => i.SomePropery = true,Time.Never); should do it.

But I'd be more inclined to just test that the value of SomeProperty was false after the SUT is exercised, in order to decouple the actual behaviour (that SomeProperty does not end up as false, regardless of how it gets there) from the actual implementation details (that SomeProperty is never directly set).

e.g you might refactor your code later on to

public void SomeMethod(bool condition)
{
    _someInterface.SomeProperty = SomeOtherComponent.MakeTheDecision(condition)
}

Meaning your test will be guaranteed to fail and worse yet, will be meaningless in terms of the actual value of _someInterface (because it is always set in that case)

Note this means having a public accessor on SomeProperty that you can access from your test code; if you don't want to do that then you are testing a private member which is not really the point of unit testing - you should be testing public implementation only.

Just my 2c.

Upvotes: 2

Related Questions