Domanda

I have a Test method which is like this

[Test]
public void VerifyRedirectedTempCodeWithAnEmptyString()
{
    var mockStringLength = new Mock<string>();
    mockStringLength.Setup(x => x.Length).Returns(0);
    Boolean returnValue = VerifyRedirectedTempCode(mockStringLength.Object);
    Assert.AreEqual(returnValue, false);
}

There is no compilation error, but when I run this test its giving System.NotSupportedException : Type to mock must be an interface or an abstract or non-sealed class. here is my actual method

    public virtual Boolean VerifyRedirectedTempCode(string tempAuthCode)
    {
        if (tempAuthCode != null && tempAuthCode.Length > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

So, how to mock the string.length property.So that even in future if they update the length method it should not affect my test method. How to mock?

È stato utile?

Soluzione

You don't need to mock the string length here. The method you're testing expects an integer, so just pass it an integer! If you really want you can pass it string.Empty.Length, in case this changes in a future version of the framework.

With a unit test, you're testing the behaviour of a method given its inputs and the state of its dependencies. If your method takes an int and returns a bool then all you need to do to test it is to pass in an int. The method shouldn't care where it came from. This is a matter of separation of concerns.


Following your update, given your method takes a string you just need to test its behaviour given different string inputs. At least null, string.Empty, and some valid string.

You can't expect your test to never fail as you change your method's implementation. In fact, you should change your test first so it DOES fail, the change your code so the tests pass, then refactor. This is called the red, green, refactor cycle.


It seems like your validator is probably part of a larger piece of work and maybe what you're really interested in testing is how the rest of your code behaves given the different potential validation results. In this case, I would recommend that you extract your validation logic into a separate class whose interface you can then mock. Supply the validator as a dependency to the code that needs it. Then, in your tests you can supply a mock validator that behaves in a predetermined way. That way you can write your tests without worrying that a future change to the validator logic will break them. This seems to be the essence of your question.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top