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'");
Related
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.
Given the following class and test
public class UserService
{
private IUserRepository _userRepo;
public UserService(IUserRepository userRepo)
{
_userRepo = userRepo;
}
public User Get(int id)
{
var user = _userRepo.Get(id);
if(user == null)
throw new CustomException();
return user;
}
}
Unit Tests:
[Fact]
public void MissingUser_ThrowsException()
{
// Arrange
var userService = new UserService(null);
// Act
Action result = userService.Get(0);
// Assert
result.Throws<CustomException>();
}
[Fact]
public void ExistingUser_ReturnsUser()
{
// Arrange
var user = new User()
{
Id = 0
};
var userRepo = new Mock<IUserRepository>();
userRepo
.Setup(m => m.Get(0))
.Return(user);
var userService = new UserService(userRepo.Object);
// Act
var result = userService.Get(0);
// Assert
Assert.Equal(user, result);
}
Is there a way to avoid passing in null parameters into the constructor when I know the dependencies will not be called in the test? If the class under test now requires a new constructor argument, I'd need to add another null parameter to this test and all other test that don't utilize that dependency.
Update:
I'm using Moq and XUnit. That is, I want to avoid using setup methods as I agree with the philosophy of XUnit. However, any mocking framework would still have the same problem.
I added another test that uses the mock. The case that I'm trying to avoid is having to deal with adding additional parameters to the constructor of the class under test when I don't need to.
If I were to add another dependency in the constructor of UserService that is used by the Get method, I would want only the second test to fail at run time. Currently, I would need to add another parameter to the ctor of UserService for both tests.
The more I think about this, the more I realize I want to use a IoC to construct my concrete (class under test). Is using an DI/IoC container in unit tests recommended?
Although it is odd that you aren't using a mocking framework, it sounds like your question relates to another issue. Many unit test will be written and the constructor for the class under test may change. What you are asking, I think, is how do you avoid the busy work of changing each and every test when you make changes to the constructor signature of the class under test?
One way to avoid this is to use a helper class to manage the construction of your test instances. Here's a simple example:
public class UserServcieMockManager
{
//mock objects here if you're using a mocking framework
public UserService GetServiceForTesting()
{
return new UserService(null); //here's where the mocks would be used
}
}
The reason I've called this class "Mock Manager" is because this is also where you would instantiate your mocks. Then when the constructor signature changes, you only have to change the one method that creates the test instance.
This type of helper class also becomes very useful as a way to centralize the setup logic for mocking scenarios that are reused between tests.
The more I think about this, the more I realize I want to use a IoC to construct my concrete (class under test). Is using an DI/IoC container in unit tests recommended?.
I prefer creation of class under test within Setup or Init method and see no reason to avoid doing it.
If you want to use IoC/DI to create your class under test, you can use AutoMoq (see on GitHub, NuGet package).
There is an exmple of usage:
[TestClass]
public class ServiceConsumerTestWithAutoMoq
{
[TestMethod]
public void DoA()
{
//arrange
var mocker = new AutoMoqer();
var sut = mocker.Create<ServiceConsumer>();
//act
sut.DoA();
//assert
mocker.GetMock<IServiceA>().Verify(it => it.Do(), Times.Once());
mocker.GetMock<IServiceB>().Verify(it => it.Do(), Times.Never());
}
[TestMethod]
public void DoB()
{
//arrange
var mocker = new AutoMoqer();
var sut = mocker.Create<ServiceConsumer>();
//act
sut.DoB();
//assert
mocker.GetMock<IServiceA>().Verify(it => it.Do(), Times.Never());
mocker.GetMock<IServiceB>().Verify(it => it.Do(), Times.Once());
}
}
public interface IServiceConsumer
{
void DoA();
void DoB();
}
public class ServiceConsumer : IServiceConsumer
{
public IServiceA serviceA { get; set; }
public IServiceB serviceB { get; set; }
public ServiceConsumer(
IServiceA serviceA,
IServiceB serviceB)
{
this.serviceA = serviceA;
this.serviceB = serviceB;
}
public void DoA()
{
serviceA.Do();
}
public void DoB()
{
serviceB.Do();
}
}
public interface IServiceA
{
void Do();
}
public interface IServiceB
{
void Do();
}
There is another library Moq.AutoMocker that is developed by member of Moq Team, Tim Kellogg.
But I'd rather use Setup or Init method to create class under test.
There is code example that I would use to solve your issue.
[TestClass]
public class ServiceConsumerTestWithInit
{
private Mock<IServiceA> serviceAMock;
private Mock<IServiceB> serviceBMock;
private IServiceConsumer sut;
[TestInitialize]
public void Initialize()
{
serviceAMock = new Mock<IServiceA>();
serviceBMock = new Mock<IServiceB>();
sut = new ServiceConsumer(
serviceAMock.Object,
serviceBMock.Object);
}
[TestMethod]
public void DoA()
{
//act
sut.DoA();
//assert
serviceAMock.Verify(it => it.Do(), Times.Once());
serviceBMock.Verify(it => it.Do(), Times.Never());
}
[TestMethod]
public void DoB()
{
//act
sut.DoB();
//assert
serviceAMock.Verify(it => it.Do(), Times.Never());
serviceBMock.Verify(it => it.Do(), Times.Once());
}
}
Instead of passing null, I'd mock IUserRepository and simply pass the mocked object.
This way a check against null doesn't throw e.g. an ArgumentException... (if you would implement such checks which is pretty handy in DI code).
If you still do not want that, implement another empty ctor for testing. Mark it internal and make the assembly internals visible to your test project. Or protected and have a derived test class.
No there is no way you can force the caller to always pass a not null value.
The best you can do is use factory pattern to pass IRepositoryFactory to the constructor so you will only have 1 parameter and will need to check for null for only that parameter.
Your RepositoryFactory will return the types for each repository you will need.
How to implement a generic RepositoryFactory?
It sound like you are looking for a Mock framework.
Personally, I Prefer Rhino Mocks
I am not sure I remember the syntax for it, but it is very easy. If I am not mistaking it is something like:
var mockedUserReop = MockRepository.GenerateMock<IUserRepository >();
The full method will be:
[TestInitialize, SetUp]
public void TestInitilize()
{
var mockedUserReop = MockRepository.GenerateMock<IUserRepository >();
UserService = new UserService(mockedUserReop );
}
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.
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 have seen many posts and questions about "Mocking a private method" but still cannot make it work and not found a real answer.
Lets forget the code smell and you should not do it etc....
From what I understand I have done the following:
1) Created a class Library "MyMoqSamples"
2) Added a ref to Moq and NUnit
3) Edited the AssemblyInfo file and added
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: InternalsVisibleTo("MyMoqSamples")]
4) Now need to test a private method.Since it's a private method it's not part of an interface.
5) added the following code
[TestFixture]
public class Can_test_my_private_method
{
[Test]
public void Should_be_able_to_test_my_private_method()
{
// TODO how do I test my DoSomthing method?
}
}
public class CustomerInfo
{
public string Name { get; set; }
public string Surname { get; set; }
}
public interface ICustomerService
{
List<CustomerInfo> GetCustomers();
}
public class CustomerService : ICustomerService
{
public List<CustomerInfo> GetCustomers()
{
return new List<CustomerInfo> { new CustomerInfo { Surname = "Bloggs", Name = "Jo" } };
}
protected virtual void DoSomething()
{
}
}
Could you provide me an example on how you would test my private method?
Thanks a lot
The steps you're describing set Moq up to test internal classes and members so have nothing really to do with testing a protected or private method
Testing private methods is a bit of a smell, you should really test just the public API. If you feel that the method is really important and needs to be tested in isolation perhaps it deserves to be in its own class where it can then be tested on its own?
If your heart is set on testing the protected method above you can roll your own Mock in your test assembly:
public class CustomerServiceMock : CustomerService {
public void DoSomethingTester() {
// Set up state or whatever you need
DoSomething();
}
}
[TestMethod]
public void DoSomething_WhenCalled_DoesSomething() {
CustomerServiceMock serviceMock = new CustomerServiceMock(...);
serviceMock.DoSomethingTester();
}
If it was private you could probably do something dodgy with reflection but going that route is the way to testing hell.
Update
While you've given sample code in your question I don't really see how you want to "test" the protected method so I'll come up with something contrived...
Lets say your customer service looks like this:-
public CustomerService : ICustomerService {
private readonly ICustomerRepository _repository;
public CustomerService(ICustomerRepository repository) {
_repository = repository;
}
public void MakeCustomerPreferred(Customer preferred) {
MakePreferred(customer);
_repository.Save(customer);
}
protected virtual void MakePreferred(Customer customer) {
// Or more than likely some grungy logic
customer.IsPreferred = true;
}
}
If you wanted to test the protected method you can just do something like:-
[TestClass]
public class CustomerServiceTests {
CustomerServiceTester customerService;
Mock<ICustomerRepository> customerRepositoryMock;
[TestInitialize]
public void Setup() {
customerRepoMock = new Mock<ICustomerRepository>();
customerService = new CustomerServiceTester(customerRepoMock.Object);
}
public class CustomerServiceTester : CustomerService {
public void MakePreferredTest(Customer customer) {
MakePreferred(customer);
}
// You could also add in test specific instrumentation
// by overriding MakePreferred here like so...
protected override void MakePreferred(Customer customer) {
CustomerArgument = customer;
WasCalled = true;
base.MakePreferred(customer);
}
public Customer CustomerArgument { get; set; }
public bool WasCalled { get; set; }
}
[TestMethod]
public void MakePreferred_WithValidCustomer_MakesCustomerPreferred() {
Customer customer = new Customer();
customerService.MakePreferredTest(customer);
Assert.AreEqual(true, customer.IsPreferred);
}
// Rest of your tests
}
The name of this "pattern" is Test specific subclass (based on xUnit test patterns terminology) for more info you might want to see here:-
http://xunitpatterns.com/Test-Specific%20Subclass.html
Based on your comments and previous question it seems like you've been tasked with implementing unit tests on some legacy code (or made the decision yourself). In which case the bible of all things legacy code is the book by Michael Feathers. It covers techniques like this as well as refactorings and techniques to deal with breaking down "untestable" classes and methods into something more manageable and I highly recommend it.
There are appear to be two parts to your question.
How do I mock a protected method:
http://blogs.clariusconsulting.net/kzu/mocking-protected-members-with-moq/
how do I trigger the invocation of this protected/private behavior in my test
The answer here is that you trigger it via something public. If you want to force it to happen directly (i.e., actually invoke something protected directly without an intermediate helper, you'll need to use reflection. This is by design - the languages are providing the protection mechanisms as a way of enforcing encapsulation.
I suggest you think about what you're trying to demonstrate/prove in your test though. If you find yourself writing a test that's complicated, you're Doing It Wrong. Perhaps what you want to do can be broken down into independent tests? Perhaps you are writing an integration test, not a unit test? But there are lots of articles out there on bad tests, and more an more will make sense to you as you learn to write good tests. Two of my favourites are http://www.codethinked.com/post/2009/06/30/What-is-Unit-Testing.aspx and http://www.codethinked.com/post/2009/11/05/Ite28099s-Okay-To-Write-Unit-Tests.aspx