Skip to content

Instantly share code, notes, and snippets.

@NickJosevski
Created October 19, 2011 01:29
Show Gist options
  • Save NickJosevski/1297265 to your computer and use it in GitHub Desktop.
Save NickJosevski/1297265 to your computer and use it in GitHub Desktop.
Mocking extension methods
//I saw this and thought there was a simple way around subbing extension methods
//http://blogs.clariusconsulting.net/kzu/how-to-mock-extension-methods/
//My choice of solution was to just refactor the IRepo interface
namespace NSubIssueTests
{
[TestFixture]
public class ExtensionOnInterfaceTests
{
[Test]
public void NSubstitute_ReturnsForAnyArgs_ExpectSubstitutedValue()
{
//arrange
var userRepo = Substitute.For<IRepo<User>>();
userRepo.AddOrAttach(new User()).ReturnsForAnyArgs(new User { Id = Guid.NewGuid() });
var mu = new ManageUsers(userRepo);
//act
var result = mu.MethodNotBehavingAsExpectedWithSubstitution(new User());
//assert
Assert.AreNotEqual(Guid.Empty, result);
}
}
public static class Extensions
{
//Here: I thought because it extends an interface 'IRepo<>' there might have been some way to stub here.
public static TResult AddOrAttach<TSrc, TResult>(this IRepo<TResult> repo, TSrc model) where TSrc : Domain
{
throw new NotSupportedException("Because we have ReturnsForAnyArgs() on this extension method do not expect to enter here");
//because I use the real IRepo here, with void return methods, stubbing it doesn't help
}
}
//-------------------------------------
//The rest is just to support the above:
public interface IRepo<TEntity>
{
void Add(TEntity e);
void Attach(TEntity e);
void AddOrAttach<TSrc, TResult>(TSrc model);
}
public class User : Domain { public String UserName { get; set; } }
public class Domain { public virtual Guid Id { get; set; } }
public class ManageUsers
{
private readonly IRepo<User> _userRepo;
public ManageUsers(IRepo<User> userRepo)
{
_userRepo = userRepo;
}
public Guid MethodNotBehavingAsExpectedWithSubstitution(User u)
{
var result = _userRepo.AddOrAttach(u);
return result.Id;
}
}
public class BasicRepo<T> : IRepo<T>
{
public void Add(T e)
{
throw new NotImplementedException();
}
public void Attach(T e)
{
throw new NotImplementedException();
}
public void AddOrAttach<TSrc, TResult>(TSrc model)
{
throw new NotImplementedException();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment