I have the following code
public ClassToTest : IClassToTest
{
private readonly DBRepository rep;
public bool MethodA()
{
//Some logic
var result=MethodB();
//Do some logic against result;
}
public ResultType MethodB()
{
return Rep.GetResult();
}
}
If I want to Unit testing MethodA, what is the best practice to test the interaction between MethodA and MethodB? I am thinking to test MethodA like testing MethodB by mocking Database dependency Rep, just like MethodA has the following implementation
public bool MethodA()
{
//Some logic
var result=Rep.GetResult();
//Do some logic against result;
}
But it is not intuitive by checking the logic in the code and the test method. I am looking for a solution similar to the one mentioned here for Java.
unit testing composite service methods
But It is not working for C#.
One extra question, What if MethodB is private, does it make any difference for the Unit testing strategy?
Update: prefer not to change the structure of the class. like not making MethodB as virtual or Move the MethodB out of the class into another test
Thanks in advance.
You don't want to test the interaction between MethodA and MethodB, you want to test that MethodA will return the expected bool result, given some context.
The fact that MethodA calls MethodB is not germaine to this test; but the fact that Rep.GetResult() will at some point be called is.
As you mentioned, you can mock the dependency Rep, so it won't matter whether MethodB is public or private.
Mock and inject the dependency
Call MethodA
Assert against the result
You want to isolate your methods that you test, that is, you want to mock MethodB while testing MethodA, and vice versa.
Also, there is a testing paradigm to test the contract (or interface) of classes. In this paradigm, you wouldn't worry about non-public non-virtual methods. I tend to mock as much as I can.
I recommend you use a mocking framework (smug, rhino mocks, moq, easymock) Smug being the coolest, but it is not yet complete - I'll just show you the code below (this is how it would work without a mocking framework to help you).
public enum ResultType
{
Ok,
NotOk,
}
public abstract class DBRepository
{
public abstract ResultType GetResult();
}
public class ClassToTest
{
public DBRepository Rep { get; set; }
public virtual bool MethodA()
{
//Some logic
var result = MethodB();
//Do some logic against result;
return result == ResultType.Ok;
}
protected virtual ResultType MethodB()
{
return Rep.GetResult();
}
}
public class DBRepositoryMock : DBRepository
{
public ResultType FakeReturn { get; set; }
public override ResultType GetResult()
{
return FakeReturn;
}
}
public class ClassToTest_MethodA : ClassToTest
{
public ResultType MethodB_FakeReturn { get; set; }
protected override ResultType MethodB()
{
return MethodB_FakeReturn;
}
}
// tests
[TestMethod]
public void Test1()
{
ClassToTest mock = new ClassToTest_MethodA();
(mock as ClassToTest_MethodA).MethodB_FakeReturn = ResultType.Ok;
Assert.IsTrue(mock.MethodA());
}
// or using injection
[TestMethod]
public static void Test2()
{
var obj = new ClassToTest();
obj.Rep = new DBRepositoryMock { FakeReturn = ResultType.NotOk };
Assert.IsFalse(obj.MethodA());
}
[TestMethod]
public void MethodAReturnsTrueGivenSomeDataAndCondition()
{
IDBRepository mockRepo = new Mock<IDBRepository>(); //Create a mock of your repository call
ClassToTest subjectToTest = new ClassToTest(mockRepo.Object); //Inject the dependency
mockRepo.SetUp(r=>r.GetResult()).Returns(someSampleTestData); //You're setting up the object that might return you true to return when mock repo will be called, by default it returns the default or null usually
var result = subjectToTest.MethodA();
mockRepo.Verify(r=>r.GetResult(), Times.Once); //Make sure your repo method was called
Assert.IsTrue(result);
}
Something like this, using Moq as a sample mocking framework.
Related
I have a base class:
public abstract class MyBaseClass
{
protected virtual void Method1()
{
}
}
and a derived class:
public class MyDerivedClass : MyBaseClass
{
public void Method2()
{
base.Method1();
}
}
I want to write a unit test for Method2 to verify that it calls Method1 on the base class. I'm using Moq as my mocking library. Is this possible?
I came across a related SO link:
Mocking a base class method call with Moq
in which the 2nd answer suggests it can be achieved by setting CallBase property to true on the mock object. However it's not clear how this would enable the call to the base class method (Method1 in the above example) to be verified.
Appreciate any assistance with this.
Unit tests should verify behavior, not implementation. There are several reasons for this:
The results are the goal, not how you get the results
Testing results allows you to improve the implementation without re-writing your tests
Implementations are harder to mock
You might be able to put in hooks or create mocks that verify that the base method was called, but do you really care how the answer was achieved, or do you care that the answer is right?
If the particular implementation you require has side effects that you can verify, then that is what you should be validating.
Mocking the base class from the perspective of the derived class is not possible. In your simple example, I would suggest one of the two options.
Option 1: In the event that MyDerivedClass really shouldn't care what MyBaseClass is up to, then use dependency injection! Yay abstraction!
public class MyClass
{
private readonly IUsedToBeBaseClass myDependency;
public MyClass(IUsedToBeBaseClass myDependency){
_myDependency = myDependency;
}
public void Method2()
{
_myDependency.Method1();
}
}
Elsewhere in test land...
[TestClass]
public class TestMyDependency {
[TestMethod]
public void TestThatMyDependencyIsCalled() {
var dependency = new Mock<IUsedToBeBaseClass>();
var unitUnderTest = new MyClass(dependency.Object);
var unitUnderTest.Method2();
dependency.Verify(x => x.Method1(), Times.Once);
}
}
Option 2: In the event that MyDerivedClass NEEDS to know what MyBaseClass is doing, then test that MyBaseClass is doing the right thing.
In alternative test land...
[TestClass]
public class TestMyDependency {
[TestMethod]
public void TestThatMyDependencyIsCalled() {
var unitUnderTest = new MyDerivedClass();
var unitUnderTest.Method2();
/* verify base class behavior #1 inside Method1() */
/* verify base class behavior #2 inside Method1() */
/* ... */
}
}
What you're describing is not a test of your code, but a test of the behavior of the language. That's fine, because it's a good way to ensure that the language behaves the way we think it does. I used to write lots of little console apps when I was learning. I wish I'd known about unit testing then because it's a better way to go about it.
But once you've tested it and confirmed that the language behaves the way you expect, I wouldn't keep writing tests for that. You can just test the behavior of your code.
Here's a real simple example:
public class TheBaseClass
{
public readonly List<string> Output = new List<string>();
public virtual void WriteToOutput()
{
Output.Add("TheBaseClass");
}
}
public class TheDerivedClass : TheBaseClass
{
public override void WriteToOutput()
{
Output.Add("TheDerivedClass");
base.WriteToOutput();
}
}
Unit test
[TestMethod]
public void EnsureDerivedClassCallsBaseClass()
{
var testSubject = new TheDerivedClass();
testSubject.WriteToOutput();
Assert.IsTrue(testSubject.Output.Contains("TheBaseClass"));
}
I currently have a base service class that all my services extend. This is what one of the methods look like:
protected internal virtual T PerformServiceOperationWithExceptionHandling<T>(Func<T> func)
{
try
{
return func.Invoke();
}
...
}
In the derived classes I call the method like this:
public AddGuestResponse AddGuest(AddGuestRequest addGuestRequest)
{
return PerformServiceOperationWithExceptionHandling(() => AddGuestLogic(addGuestRequest));
}
I want to test AddGuest and ensure "AddGuestLogic" is being passed as a parameter in the base method? How do I achieve this with nSubstitute and nUnit. I don't think its possible?
================================================
I ended up using the following code:
[Test]
public void AddGuest_WhenCalled_PerformsAddGuestLogicWithExceptionHandling()
{
Func<AddGuestResponse> addGuestLogic = null;
_guestService.PerformServiceOperationWithExceptionHandling(Arg.Do<Func<AddGuestResponse>>(arg => addGuestLogic = arg));
var addGuestRequest = new AddGuestRequest();
_guestService.AddGuest(addGuestRequest);
_guestService.ClearReceivedCalls();
addGuestLogic.Invoke();
_guestService.Received().AddGuestLogic(addGuestRequest);
}
The _guestService is created in my setup method as follows: Substitute.ForPartsOf();
I second Sunny Milenov's answer, but would go one step further by advising you to change your design. I have learned the hard way that many of these headaches with testing base class behavior go away when you follow the principle of composition over inheritance.
I.e., if you refactor your base class to a collaborator, which you inject into your services' constructor, you can test that in isolation and mock it in your services' tests. No worrying about testing an abstract base class or testing the same exception handling in all of your services' tests.
You would test that the collaborator correctly invokes the func in the collaborator's tests.
In the services' tests you can just mock the collaborator to return the Func's result right away:
[Test]
public void ServiceLogicIsExecuted()
{
var collaborator = Substitute.For<ICollaborator>();
//Tell the test double to return the Func's result. You'd probably want to do this in the setup method.
collaborator.PerformServiceOperation(Arg.Any<Func<int>>()).Returns(x => ((Func<int>)x[0]).Invoke());
var sut = new Service(collaborator);
var result = sut.CalculateSomething();
Assert.That(result, Is.EqualTo(99));
}
public class Service
{
private readonly ICollaborator _collaborator;
public Service(ICollaborator collaborator)
{
_collaborator = collaborator;
}
public int CalculateSomething()
{
return _collaborator.PerformServiceOperation(ExecuteLogic);
}
private static int ExecuteLogic()
{
return 99;
}
}
public interface ICollaborator
{
T PerformServiceOperation<T>(Func<T> func);
}
Short answer - you shouldn't. Unit testing is about testing the behavior of the tested method, not the implementation details.
Long answer:
It doesn't matter how the class internally works, as far as it produces the expected results.
You need to test your public method on the final class and see if this works as expected. Testing a base/abstract class in isolation proves nothing.
I am new to unit testing and I would like some help. I am using code first with repository pattern. I have a generic repository which contains generic CRUD operation called Generic Repository ( see blow )
public abstract class GenericRepository<T> where T : class
{
private HolidayDatabaseContext _dataContext;
private readonly IDbSet<T> _dbset;
protected GenericRepository(IDbFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
_dbset = DataContext.Set<T>();
}
protected IDbFactory DatabaseFactory
{
get;
private set;
}
protected HolidayDatabaseContext DataContext
{
get { return _dataContext ?? (_dataContext = DatabaseFactory.Get()); }
}
public virtual void Add(T entity)
{
_dbset.Add(entity);
}
public virtual void Update(T entity)
{
_dataContext.Entry(entity).State = EntityState.Modified;
}
public virtual void Delete(T entity)
{
_dbset.Remove(entity);
}
public virtual IEnumerable<T> Enumerable()
{
return _dbset.AsEnumerable<T>();
}
public virtual IQueryable<T> List()
{
return _dbset.AsQueryable<T>();
}
public virtual T GetSingleById(int id)
{
return _dbset.Find(id);
}
public void Save()
{
_dataContext.SaveChanges();
}
}
I have then inherited it into a User Repository and created some specific methods. see below
public class UserRepository : GenericRepository<User>, IUserRepository
{
public UserRepository(IDbFactory databaseFactory)
: base(databaseFactory) { }
public int HolidayEntitlement(int userId)
{
return HolidayEntitlement(userId, DateTime.Now);
}
public int HolidayEntitlement(int userId, DateTime dateTime)
{
//Get the User
var user = this.GetSingleById(userId);
//Work Total Entitlement
int entitlement = user.BaseHolidayEntitlement;
//Years in Service
entitlement += (dateTime - user.EmploymentStartDate).Days / 365;
return entitlement;
}
public int RemainingHolidayEntitlement(int userId)
{
return RemainingHolidayEntitlement(userId, DateTime.Now);
}
public int RemainingHolidayEntitlement(int userId, DateTime dateTime)
{
return int.MinValue;
}
}
I would like to Unit test HolidayEntitlement(int userId, DateTime dateTime) but i need to mock the GetSingleById part in the method
I have written this as a Test but it doesn't compile.
[TestMethod]
public void GetHolidayEntitlement25()
{
//How to write this Unit test
//Setup
var user = new User { AnnualHolidayIncrement = 1, BaseHolidayEntitlement = 25, EmploymentStartDate = new DateTime(2013, 1, 1),Id=1 };
Mock<UserRepository> mock = new Mock<UserRepository>();
mock.Setup(m => m.GetSingleById(1)).Returns(user);
Assert.AreEqual(25, mock.Object.HolidayEntitlement(1));
}
Any help would be appreciated
You seem to be saying that you only want to mock part of the interface. When you start encountering this sort of situation it suggests that you are mixing your concerns and probably doing something wrong somewhere.
In this instance your Repository is doing MUCH more than just CRUD and therefore has multiple responsibilities (it should only have one, lookup SOLID programming). You are performing Business logic in the repository and it should not live there! Anything other than simple CRUD operations should be moved out into the Business Logic Layer. I.e. your HolidayEntitlement method calculates something by applying some logic and is therefore NOT a CRUD / repository operation!
So... What you should do is move the business logic bits out into a new class, say UserLogic. Within the UserLogic class you would use an injected IUserRepository to communicate with your repository. In UserLogic that is where you would put your HolidayEntitlement method and it would make a call to IUserRepository.GetSingleById. So, when you then test your UserLogic class you would inject in your mock IUserRepository that would have the stub version of GetSingleById and then you will be back on the right track!
I hope that makes sense / helps?!
--ORIGINAL POST--
P.S. My original post stated that you should mock interfaces, not instances so this still applies and I will leave here for reference:
You should be mocking IUserRepository NOT UserRepository.
That is because UserRepository is an implementation of IUserRepository. You want to say that you are giving it a NEW implementation, i.e. your mock. At the moment you are using the ACTUAL class UserRepository.
Mocking is generally used when you need to supply a fake dependency and in this case you appear to be trying to Mock the System Under Test (SUT) which doesn't really make sense - there's literally no point because your test is not actually telling you anything about the behaviour of UserRepository; all you are doing is testing if you setup your Mock correctly which isn't very useful!
The test code you have given seems to indicate that you want to test UserRepository.HolidayEntitlement.
I would be much more inclined to move functions like that out of your Repository class and into a separate business-logic type class. This way you can test the logic of calculating a user's holiday entitlement in total isolation which is a major principle of unit testing.
In order to test that this function does what it's supposed to do (i.e perform a calculation based on properties of a User) you need to ensure that whatever User instance is being operated on within that function is 100% isolated and under your control - either with a Mock or Fake (Stub) instance of User, in this case Mocks are an excellent choice because you only need to implement the parts of the dependency that your SUT is going to need.
So, what you could do is this:
Define an interface for User
public interface IUser
{
int BaseHolidayEntitlement{get;set;}
DateTime EmploymentStartDate {get;set;}
//other properties for a User here
}
Implement this on your User class
public class User:IUser
{
//implemement your properties here
public int BaseHolidayEntitlement{get;set;}
public DateTime EmploymentStartDate {get;set;}
//and so on
}
Create a class for User logic
public class UserRules
{
public int GetHolidayEntitlement(IUser user,DateTime dateTime)
{
//perform your logic here and return the result
}
}
Now your test becomes much simpler and doesn't even need the repository
[TestMethod]
public void GetHolidayEntitlement_WithBase25_Returns25()
{
//Arrange
var user = new Mock<IUser>();
//setup known, controlled property values on the mock:
user.SetupGet(u=>u.BaseHolidayEntitlement).Returns(25);
user.SetupGet(u=>u.EmploymentStartDate).Returns(new DateTime(2013,1,1));
var sut = new UserRules();
int expected = 25;
//Act
int actual = sut.GetHolidayEntitlement(user.Object,DateTime.UtcNow);
//Assert
Assert.AreEqual(expected,actual,"GetHolidayEntitlement isn't working right...");
}
How can I test the IsHappy function using Moles?
class SomeClass
{
protected virtual bool IsHappy(string mood)
{
return (mood == "Happy");
}
}
I tried to test if by using Stub:
SSomeClass stub = new SSomeClass();
stub.CallBase = true;
Assert.IsTrue(stub.IsHappyString("Happy"));
... but the IsHappyString method returns null thus throwing a NullReference exception.
So, how can I test the default implementation of IsHappy method?
I'd forget about stubs here. Stubs/mocks are for when you want to fake the behavior of a dependency. You'd stub your SomeClass if had SomeClassClient that you wanted to test and it used SomeClass:
public class Foo
{
public virtual int GetFoosInt()
{
return 12;
}
}
public class FooClient
{
private Foo _foo;
public FooClient(Foo foo)
{
_foo = foo;
}
public int AddOneToFoosInt()
{
return _foo.GetFoosInt() + 1;
}
}
In this example, when testing FooClient, what you want to test is that it returns one more than "GetFoosInt()". You don't actually care what FoosInt is for testing the FooClient. So, you create a Foo stub where you can setup GetFoosInt to return whatever you want.
In your case, testing a protected virtual member, I'd go with this:
[TestClass]
public class SomeClassTest
{
private class DummySomeClass : SomeClass
{
public bool IsHappyWrapper(string mood)
{
return IsHappy(mood);
}
}
[TestMethod]
public void SomeTest()
{
var myClass = new DummySomeClass();
Assert.IsTrue(myClass.IsHappyWrapper("Happy"));
}
}
This gives you 'direct' access to the protected virtual to test default behavior. Only word of caution is that if you start defining abstract members and adding to SomeClass in general, you'll have to add them to this dummy inheritor as well, adding to testing maintenance overhead.
The purist in me says that you should leave protected members alone and only test them through the public interface. But, that may or may not be practical in your situation, and I don't really see any harm in this approach.
Stubs and Moles are for isolating a class from any dependencies it has, either environmental dependencies or class dependencies. This class has no dependencies whatsoever, so why are you trying to mole or stub it?
If you want to make sure this base class works properly when people override it, then you'll need to create a test implementation. In that case this is more or less what your test cases should look like:
public SomeClassTestAdapter : SomeClass
{
public bool GetIsHappy(string mood)
{
return IsHappy(mood);
}
}
[Test]
public void ShouldReturnTrueWhenPassedHappy()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy("Happy");
Assert.IsTrue(result, "Expected result to be true");
}
[Test]
public void ShouldReturnFalseWhenPassedLowerCaseHappy()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy("happy");
Assert.IsFalse(result, "Expected result to be false");
}
[Test]
public void ShouldReturnFalseWhenPassedNull()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy(null);
Assert.IsFalse(result, "Expected result to be false");
}
Etc.
There is no place in this code that stubs or moles should be squeezed in.
If you don't want to create an adapter class for this case, you can use built-in .Net features rather than a big, paid dependency like Moles. Reflections and dynamic let you get access to protected or private members. See this example:
http://igoro.com/archive/use-c-dynamic-typing-to-conveniently-access-internals-of-an-object/
I've written some Unit Tests using Rhino Mocks and I'm happy with the results except for the fact that I have had to expose the underlying web service as public virtual (isUserInRoleWebService) presumably because this is my stub in the partial mock.
I usually use reflection to avoid exposing private methods but this will not work on the mocked object.
Has anyone got around this ? Must be a common scenario.
[SetUp]
public void SetUp()
{
_mockRepository = new MockRepository();
_entitlementCache = _mockRepository.PartialMock<EntitlementCache>();
}
[Test]
// simple test to verify membership of a single role
public void Test_SingleRoleMember()
{
(new ReflectedObject(_entitlementCache)).InvokeInstanceMethod(
"setRoleHierachy",
new object[] { hierachy2Level }
);
using (_mockRepository.Record())
{
// I had to convert isUserInRoleWebService to public :-(
_entitlementCache.Stub(x => x.isUserInRoleWebService("user", "Role 1"))
.Repeat
.Once()
.Return(true);
}
using (_mockRepository.Playback())
{
bool res = _entitlementCache.IsUserInRole("user", "Role 1");
Assert.AreEqual(true, res, "user member of 'Role 1'");
}
}
[TearDown]
public void TearDown()
{
_mockRepository.ReplayAll();
_mockRepository.VerifyAll();
}
You can use partial mocks to override protected internal virtual methods. Note that you'll need to specify [InternalsVisibleTo("YourTestProject")] in the project-under-test's AssemblyInfo.cs.
protected internal (or protected internal, if you prefer) is a union of protected and internal. So, internal+[InternalsVisibleTo] makes the method visible to your test project, and protected allows Rhino to override the virtual method.
As a rule, I don't test or mock private methods. It seems like it might be better for you in this case to make the web service itself available as property on your cache, and then mock that. For example:
IWebService service = ...
service.Expect(s => s.IsUserInRoleWebService("user", "Role 1")).Return(true);
EntitlementCache cache = ...
cache.Service = service;
bool result = cache.IsUserInRole("user", "Role 1");
Assert.IsTrue(result, "user member of 'Role 1'");