Tag Archives: Mock

Using NSubstitute for partial mocks

I have previously written about how to, effectively, subclass using Nsubstitute; in this post, I’ll cover how to partially mock out that class.

Before I get into the solution; what follows is a workaround to allow badly written, or legacy code to be tested without refactoring. If you’re reading this and thinking you need this solution then my suggestion would be to refactor and use some form of dependency injection. However, for various reasons, that’s not always possible (hence this post).

Here’s our class to test:

public class MyFunkyClass
{
    public virtual void MethodOne()
    {        
        throw new Exception("I do some direct DB access");
    }
 
    public virtual int MethodTwo()
    {
        throw new Exception("I do some direct DB access and return a number");

        return new Random().Next(5);
    }
 
    public virtual int MethodThree()
    {
        MethodOne();
        if (MethodTwo() <= 3)
        {
            return 1;
        }
 
        return 2;
    }
}

The problem

Okay, so let’s write our first test:

[Fact]
public void Test1()
{
    // Arrange
    MyFunkyClass myFunkyClass = new MyFunkyClass();
 
    // Act
    int result = myFunkyClass.MethodThree();
 
    // Assert
    Assert.Equal(2, result);
}

So, what’s wrong with that?

Well, we have some (simulated) DB access, so the code will error.

Not the but a solution

The first thing to do here is to mock out MethodOne(), as it has (pseudo) DB access:

[Fact]
public void Test1()
{
    // Arrange
    MyFunkyClass myFunkyClass = Substitute.ForPartsOf<MyFunkyClass>();
    myFunkyClass.When(a => a.MethodOne()).DoNotCallBase();
 
    // Act
    int result = myFunkyClass.MethodThree();
 
    // Assert
    Assert.Equal(2, result);
}

Running this test now will fail with:

Message: System.Exception : I do some direct DB access and return a number

We’re past the first hurdle. We can presumably do the same thing for MethodTwo:

[Fact]
public void Test1()
{
    // Arrange
    MyFunkyClass myFunkyClass = Substitute.ForPartsOf<MyFunkyClass>();
    myFunkyClass.When(a => a.MethodOne()).DoNotCallBase();
    myFunkyClass.When(a => a.MethodTwo()).DoNotCallBase();
 
    // Act
    int result = myFunkyClass.MethodThree();
 
    // Assert
    Assert.Equal(2, result);
}

Now when we run the code, the test still fails, but it no longer accesses the DB:

Message: Assert.Equal() Failure
Expected: 2
Actual: 1

The problem here is that, even though we don’t want MethodTwo to execute, we do want it to return a predefined result. Once we’ve told it not to call the base method, you can then tell it to return whatever we choose (there are separate events – see the bottom of this post for a more detailed explanation of why); for example:

[Fact]
public void Test1()
{
    // Arrange
    MyFunkyClass myFunkyClass = Substitute.ForPartsOf<MyFunkyClass>();
    myFunkyClass.When(a => a.MethodOne()).DoNotCallBase();
    myFunkyClass.When(a => a.MethodTwo()).DoNotCallBase();
    myFunkyClass.MethodTwo().Returns(5);
 
    // Act
    int result = myFunkyClass.MethodThree();
 
    // Assert
    Assert.Equal(2, result);
}

And now the test passes.

TLDR – What is this actually doing?

To understand this better; we could do this entire process manually. Only when you’ve felt the pain of a manual mock, can you really see what mocking frameworks such as NSubtitute are doing for us.

Let’s assume that we don’t have a mocking framework at all, but that we still want to test MethodThree() above. One approach that we could take is to subclass MyFunkyClass, and then test that subclass:

Here’s what that might look like:

class MyFunkyClassTest : MyFunkyClass
{
    public override void MethodOne()
    {
        //base.MethodOne();
    }
 
    public override int MethodTwo()
    {
        //return base.MethodTwo();
        return 5;
    }
}

As you can see, now that we’ve subclassed MyFunkyClass, we can override the behaviour of the relevant virtual methods.

In the case of MethodOne, we’ve effectively issued a DoNotCallBase(), (by not calling base!).

For MethodTwo, we’ve issued a DoNotCallBase, and then a Returns statement.

Let’s add a new test to use this new, manual method:

[Fact]
public void Test2()
{
    // Arrange 
    MyFunkyClassTest myFunkyClassTest = new MyFunkyClassTest();
 
    // Act
    int result = myFunkyClassTest.MethodThree();
 
    // Assert
    Assert.Equal(2, result);
}

That’s much cleaner – why not always use manual mocks?

It is much cleaner if you always want MethodThree to return 5. Once you need it to return 2 then you have two choices, either you create a new mock class, or you start putting logic into your mock. The latter, if done wrongly can end up with code that is unreadable and difficult to maintain; and if done correctly will end up in a mini version of NSubstitute.

Finally, however well you write the mocks, as soon as you have more than one for a single class then every change to the class (for example, changing a method’s parameters or return type) results in a change to more than one test class.

It’s also worth mentioning again that this problem is one that has already been solved, cleanly, by dependency injection.

Short Walks – NSubstitute – Subclassing and Partial Substitutions

I’ve had this issue a few times recently. Each time I have it, after I’ve worked out what it was, it makes sense, but I keep running into it. The resulting frustration is this post – that way, it’ll come up the next time I search for it on t’internet.

The Error

The error is as follows:

“NSubstitute.Exceptions.CouldNotSetReturnDueToNoLastCallException: ‘Could not find a call to return from.”

Typically, it seems to occur in one of two circumstances: substituting a concrete class and partially substituting a concrete class; that is:

var myMock = Substitute.ForPartsOf<MyClass>();

Or:

var myMock = Substitute.For<MyClass>();

Why?

If you were to manually mock out an interface, how would you do that? Well, say you had IMyClass, you’d just do something like this:

public class MyClassMock : IMyClass 
{
	// New and imaginative behaviour goes here
}

All’s good – you get a brand new implementation of the interface, and you can do anything with it. But what would you do if you were trying to unit test a method inside MyClass that called another method inside MyClass; for example:

public class MyClass : IMyClass
{
	public bool Method1()
{
		int rowCount = ReadNumberOfRowsInFileOnDisk();
		Return rowCount > 10;
	}
	
	public int ReadNumberOfRowsInFileOnDisk()
	{
		// Opens a file, reads it, and returns the number of rows
	}
}

(Let’s not get bogged down in how realistic this scenario is, or whether or not this is good practice – it illustrates a point)

If you want to unit test Method1(), but don’t want to actually read a file from the disk, you’ll want to replace ReadNumberOfRowsInFileOnDisk(). The only real way that you can do this is to subclass the class; for example:

public class MyClassMock : MyClass

You can now test the behaviour on MyClass, via MyClassMock; however, you still can’t* override the method ReadNumberOfRowsInFileOnDisk() because it isn’t virtual. If you make the method virtual, you can override it in the subclass.

The same is true with NSubstitute – if you want to partially mock a class in this way, it follows the same rules as you must if you would to roll your own.

Footnotes

* There may, or may not be one or two ways to get around this restriction, but let’s at least agree that they are, at best, unpleasant.

Mocking IPrinciple.Identity and Claims in NSubstitute

In ASP.Net, there is a concept of an identity. Built on top of this is an authentication system based on claims; allowing applications to implement a claims based authentication system. That is, I can determine if my user has “Administrator” privileges in the following syntax:

var claim = ClaimsIdentity.FindFirstValue("Administrator");

For more information about how claims work, see this excellent explanation. This post is not really concerned with how claims work, but rather, how to mock them out; which is much more difficult than you might guess.

In the references below, you’ll see a number of different strategies to mock out the claims and principle objects. There also seems to be a loose consensus that even attempting to do this is folly. However, I’ve cobbled together a set of mocks using NSubstitute that work. I’m not claiming that they work in all cases, or that they will work in any situation other than the specific one that I am trying to solve; but it did work for that, and so I thought it useful enough to share.

var myController = new MyController();
 
var mockClaim = new Claim("Administrator", "test");
 
var identity = Substitute.For<ClaimsIdentity>();
identity.Name.Returns("test");
identity.IsAuthenticated.Returns(true);
identity.FindFirst(Arg.Any<string>()).Returns(mockClaim);
 
var claimsPrincipal = Substitute.For<ClaimsPrincipal>();
claimsPrincipal.HasClaim(Arg.Any<string>(), Arg.Any<string>()).Returns(true);
claimsPrincipal.HasClaim(Arg.Any<Predicate<Claim>>()).Returns(true);
claimsPrincipal.Identity.Returns(identity);
 
var httpContext = Substitute.For<HttpContextBase>();            
httpContext.User.Returns(claimsPrincipal);
 
var controllerContext = new ControllerContext(
    httpContext, new System.Web.Routing.RouteData(), myController);           
 
myController.ControllerContext = controllerContext;
 
// Act
var result = myController.TestMethod();
 
// Assert
// . . .

Remember that this is only necessary if you are trying to access claims based on the identity within the `TestMethod()`. Also, I’ll remind the reader that I assert only that this worked in the specific situation that I needed it to, but it’s probably a good starting point for others.

References

https://volaresystems.com/blog/post/2010/08/19/Dont-mock-HttpContext

http://nsubstitute.github.io/help/set-return-value/

https://stackoverflow.com/questions/1389744/testing-controller-action-that-uses-user-identity-name

https://stackoverflow.com/questions/13579519/mock-authenticated-user-using-moq-in-unit-testing

https://stackoverflow.com/questions/14190066/is-there-any-way-i-can-mock-a-claims-principal-in-my-asp-net-mvc-web-application

https://stackoverflow.com/questions/22762338/how-do-i-mock-user-identity-getuserid/23960592

https://dotnetcodr.com/2013/02/11/introduction-to-claims-based-security-in-net4-5-with-c-part-1/

Mock Current Date and Time in SQL Server

Occasionally, if you’re especially lucky, you’ll get into a situation where you have SQL procedures and functions that are so complicated that they require unit tests all of their own. They’ll have business logic embedded in them, and not testing them will leave a massive hole in your test coverage.

In this blog post I’m not going to describe how to do that – SSDT are quite well documented anyway. This is about how to deal with dates and times in SQL Server.

A new function

You’ll probably have a few places in your SQL script that call the following:

SELECT GETUTCDATE()

Or, you may even have the following:

SELECT GETDATE()

Which will presumably work well for what you want. Of course, the problem that you have here is, that for unit tests, this presents a variable factor in your test; that is, you’re not always testing the same procedure. Take the following segments of SQL for example:

PROCEDURE MYPROC
AS
BEGIN
	DECLARE @today DATETIME
	DECLARE @hasEntriesAfterToday INT
	
	SET @today = GETUTCDATE()

	SELECT @hasEntriesAfterToday = COUNT(*)
	FROM dbo.MyTable t
	WHERE t.Col1 > @today

	IF (@hasEntriesAfterToday > 0) 	
		select 'test'
END
GO

MyTable contains many entries after today, and my test checks that it returns ‘test’, so the test works, the code works and I’m going to bed.

But what happens in a year’s time?

Let’s say that the last entity in that table is 01/01/2015 (that way the post works in the US, too). As I write this, it is mid-way through June. So, I need to know what will happen on 2nd January 2015. If I do nothing then when it is 2nd January 2015 the test will start to fail, and I won’t know why.

Abstract the date

When faced with this problem, my initial fix was as follows:

CREATE FUNCTION dbo.MyGetDate()
RETURNS DATETIME
AS
BEGIN
	DECLARE @today DATETIME
	SET @today = GETUTCDATE()

	RETURN @today
END

And then simply change the above procedure to call this. That certainly works; however, as soon as you start to reference this function (for example, you set a default value for a date in a table), you’ll find that you’ll get stuck when you try to mock it out; consequently, you need a double layer:

CREATE FUNCTION dbo.MyGetDate2()
RETURNS DATETIME
AS
BEGIN
	DECLARE @today DATETIME	
	SET @today = GETUTCDATE()

	RETURN @today
END
GO

CREATE FUNCTION dbo.MyGetDate()
RETURNS DATETIME
AS
BEGIN
	DECLARE @today DATE	
	SET @today = dbo.MyGetDate2()

	RETURN @today
END
GO

What this then allows you to do is to replace the function of MyGetDate2 without affecting MyGetDate. This is a wrapper function to replace the DateTime:

internal static void OverrideDateTimeTest(SqlConnection cn, SqlTransaction tr, string newDateTime)
{
    string sql =
        "ALTER FUNCTION dbo.MyGetDate2(	" +
        ") RETURNS datetime " +
        "AS " +
        "BEGIN " +
        "DECLARE @value datetime " +
        "SET @value = convert(datetime, '" + newDateTime + "') "  +
        "RETURN @value " +
        "END";
 
    using (SqlCommand cmd = new SqlCommand(sql, cn, tr))
    {
        cmd.Connection = cn;
        cmd.CommandType = CommandType.Text;
        cmd.ExecuteNonQuery();
    }
}

And here’s the test:

[TestMethod]
public void MyTest()
{
    DBWrapper.OverrideDateTimeTest(cn, tr, "2014-06-10 22:30:00.000");
    Assert.AreEqual( …

The best part about this is that IN SQL SERVER DDL STATEMENTS CAN BE ROLLED BACK! Look at the following test:

-- 1
BEGIN TRAN
GO

-- 2
SELECT dbo.MyGetDate()
GO

-- 3
ALTER FUNCTION [dbo].[MyGetDate2]()
RETURNS DATETIME
AS
BEGIN
	DECLARE @today DATETIME
	SET @today = GETUTCDATE()

	RETURN @today
END
GO

-- 4
SELECT dbo.MyGetDate()
GO

-- 5
ALTER FUNCTION [dbo].[MyGetDate2]()
RETURNS DATETIME
AS
BEGIN
	DECLARE @today DATETIME
	SET @today = CONVERT(DATETIME, '2014-06-10 22:30:00.000')

	RETURN @today
END
GO

-- 6
SELECT dbo.MyGetDate()
GO

-- 7
ROLLBACK TRAN
GO

-- 8
SELECT dbo.MyGetDate()
GO

Okay – there’s a fair amount of code, but the stages are as follows (numbered):

1. Start the transaction.
2. Show the existing implementation of MyGetDate2 (in case it’s not what it should be).
3. Change MyGetDate2 to use GetUTCDate(), so it should be the same as before.
4. Check again – should still return the same as 2.
5. Change MgGetDate2 to return hard coded date.
6. Check that it now returns a hard coded date.
7. Rollback the transaction.
8. The transaction is rolled back, and so the function behaves as in 1.

Conclusion

So, we can include a date mock in our test and, should there be a problem, or when we’re finished, it all gets rolled back. Just because I’m always cautious about such things, I’ve created a test that checks that the default implementation returns the current date, but you shouldn’t need this.