Mock a response of a inner function but test the outer function - c#

I have a C# code setup this way.
public class Client : IClient
{
public string funcA()
{
var output = funcB(1);
//Do something on output and produce finalResult
return finalResult;
}
public string funcB(int x)
{
// Some operations on produces string result
return result;
}
}
I want to mock funcB output but let the funcA perform as is based on the output from funcB.
In my test class I do the following:
public class MockClient
{
private Mock<IClient> _mockClient;
public MockClient()
{
_mockClient = new Mock<IClient>();
}
[TestMethod]
public void TestClient()
{
_mockClient.Setup(foo => foo.funcB(It.IsAny<int>())).Returns("test");
var testOutput = _mockClient.Object.funcA();
}
}
The variable testOutput returns NULL. I understand why, because the object is created from an Interface. I am not sure how to exactly work around this problem. Any inputs on this will be helpful.

I am assuming you are using Moq based off of your syntax? If so, you can use "Partial Mocks". Example:
Change funcB to be virtual
public virtual string funcB(int x)
{
// Some operations on produces string result
return result;
}
Then mock the concrete type and set the CallBase property to true:
[TestMethod]
public void TestClient()
{
Mock<Client> _mockClient = Mock<Client>();
_mockClient.CallBase = true;
_mockClient.Setup(foo => foo.funcB(It.IsAny<int>())).Returns("test");
var testOutput = _mockClient.Object.funcA();
}

Example above is totally correct in Moq syntax. But making the functions virtual or not - it's a production decision based on your, client, etc purposes and needs. Changing funcB to be virtual just for test - sounds unreasonable.
You can use Typemock Isolator for testing your original code, see:
public class Client : IClient
{
public string funcA()
{
var output = funcB(1);
//Do something on output and produce finalResult
var finalResult = "B result: " + output;
return finalResult;
}
public string funcB(int x)
{
// Some operations on produces string result
return "result";
}
}
[TestMethod, Isolated]
public void TestMethod()
{
//Arrange
var foo = new Client();
Isolate.WhenCalled(() => foo.funcB(0)).WillReturn("test");
//Act
var output = foo.funcA();
//Assert
Assert.AreEqual("B result: test", output);
}

Related

NUnit Test - How to set up a private method called inside public method to return specific value?

I am trying to test the following GetNumber public method using NUnit.
public GetNumber()
{
var numberOfUsers = GetNumberOfUsers();
var number = numberOfUsers + 1;
return number;
}
To test it fully I need the private GetNumberOfUsers method to return a specific value during the execution of the test e.g. 0 or 1. How can I set up my test so that GetNumberOfUsers returns the values that I want?
The logic of the test will be something like the below:
[Test]
public void GetNumberTest()
{
//setup GetNumberOfUsers so that it returns 0
var result = object.GetNumber();
Assert.AreEqual(1, result);
}
You can't. You should be aiming to test your public interface. You haven't given enough detail about where GetNumberOfUsers gets it's result from which makes it difficult to give you the optimum solution. You could make GetNumberOfUsers protected and override it in a subclass. e.g.
public class MyClass
{
public int GetNumbers()
{
var numberOfUsers = GetNumberOfUsers();
}
protected virtual GetNumberOfUsers()
{ // implementation }
}
public class MyClassImplForTesting : MyClass
{
public int NumberOfUsers {get; set;} = 10;
protected overrides GetNumberOfUsers()
{
return NumberOfUsers;
}
}

How to mock a normal method inside a static class in C#?

I need to mock a normal method inside a static method
My method is something like this and is it possible to mock TestResult here?
I have done with mocking a method inside a method by using an interface, but here static methods that
public static ClassData()
{
public static string GetData()
{
//Wish to mock TestResult method
TestData TD=new TestData();
string FinalResult=TD.TestResult();
//Some logic
Return FinalResult;
}
}
Split the current function into two parts:
public static ClassData()
{
public static string GetData()
{
//Wish to mock TestResult method
TestData TD=new TestData();
string FinalResult=TD.TestResult();
return GetData2(FinalResult);
}
public static string GetData2(string FinalResult)
{
//Some logic
return FinalResult;
}
}
In your test case, call GetData2 instead of GetData, and now you can test "some logic" with appropriate input values.
Note that GetData2 could be internal when you use the InternalsVisibleTo attribute.
The answer is "No, there is no way to mock without changing an existing code".
The fact that code cannot be covered with a unit test easily is a proof indicator that something is wrong with the code itself. So I'd really recommend to revisit the approach.
If this is not a practical task, you can try the following trick. Expose TestData as a property with public setter (which you'd set in the test code):
public static class ClassData
{
public static string GetData()
{
//Wish to mock TestResult method
TestData TD = new TestData();
string FinalResult = TestData.TestResult();
//Some logic
return FinalResult;
}
public static TestData TestData { private get; set; }
}
public class TestData
{
public virtual string TestResult()
{
return string.Empty;
}
}
Just an idea of a test body:
var testDataMock = new Mock<TestData>(); // Moq as example
testDataMock.Setup(t => t.TestResult()).Returns("some string");
ClassData.TestData = testDataMock.Object;
var result = ClassData.GetData();
//Assertions
Using Isolator you can simply do:
public static class ClassData
{
public static string GetData()
{
//Wish to mock TestResult method
TestData td = new TestData();
string finalResult = td.TestResult();
//Some logic
return finalResult;
}
}
[TestMethod, Isolated]
public void Test_MockFinalResult()
{
var fakeTestData = Isolate.Fake.NextInstance<TestData>();
Isolate.WhenCalled(() => fakeTestData.TestResult()).WillReturn("test");
var str = ClassData.GetData();
Assert.AreEqual("test",str);
}
Or did you have something else in mind?
There is no need to make the class static. You can have a static method inside a non static class. You can then have the static method call a non static method.
public class test
{
public static string GetData()
{
//Wish to mock TestResult method
TestData TD = new TestData();
string FinalResult = TD.TestResult();
//Some logic
return FinalResult;
}
public class TestData
{
public string TestResult()
{
return "Hello World";
}
}
}

How to return null when accessing a moq object?

I am using Moq library for unit testing. Now what i want is that when I access my object for the first time it should return null, and when i access this on second time it should return something else.
here is my code
var mock = new Mock<IMyClass>();
mock.Setup(?????);
mock.Setup(?????);
var actual = target.Method(mock.object);
in my method i am first checking that whether mock object is null or not, if it is null then do initialize it and then do some calls on it.
bool Method(IMyClass myObj)
{
if (myObj != null)
return true;
else
{
myObj = new MyClass();
bool result = myObj.SomeFunctionReturningBool();
return result;
}
}
what to do setup for mock object,
Also i need to know how to mock this line
bool result = myObj.SomeFunctionReturningBool();
It sounds like you are trying to run two tests with one test method - maybe it would be better to split the tests into two?
You also want to initialise a new object if the method is passed null. To test this, I suggest creating a factory object responsible for creating instances of MyClass. The new code would look like:
interface IMyClassFactory
{
IMyClass CreateMyClass();
}
bool Method(IMyClass myObj, IMyClassFactory myClassFactory)
{
if (myObj != null)
{
return true;
}
myObj = myClassFactory.CreateMyClass();
return myObj.SomeFunctionReturningBool();
}
Then the tests would look like:
[Test]
public void Method_ShouldReturnTrueIfNotPassedNull()
{
Assert.That(target.Method(new MyClass()), Is.True);
}
[Test]
public void Method_ShouldCreateObjectAndReturnResultOfSomeFunctionIfPassedNull()
{
// Arrange
bool expectedResult = false;
var mockMyClass = new Mock<IMyClass>();
mockMyClass.Setup(x => x.SomeFunctionReturningBool()).Returns(expectedResult);
var mockMyFactory = new Mock<IMyClassFactory>();
mockMyFactory.Setup(x => x.CreateMyClass()).Returns(mockMyClass.Object);
// Act
var result = target.Method(null, mockMyFactory.Object);
// Assert
mockMyClass.Verify(x => x.SomeFunctionReturningBool(), Times.Once());
mockMyFactory.Verify(x => x.CreateMyClass(), Times.Once());
Assert.That(result, Is.EqualTo(expectedResult));
}
Here the factory pattern has been used to pass in an object which can create objects of IMyClass type, and then the factory itself has been mocked.
If you do not want to change your method's signature, then create the factory in the class's constructor, and make it accessible via a public property of the class. It can then be overwritten in the test by the mock factory. This is called dependency injection.
Moq - Return null - This working example simply illustrates how to return null using Moq. While the line of code is required is the commented line below, a full working example is provided below.
// _mockShopService.Setup(x => x.GetProduct(It.IsAny<string>())).Returns(() => null);
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
}
public interface IShopService
{
Product GetProduct(string productId);
}
public class ShopService : IShopService
{
public Product GetProduct(string productId)
{
if (string.IsNullOrWhiteSpace(productId))
{
return new Product();
}
return new Product { Id = "8160807887984", Name = "How to return null in Moq" };
}
}
public class Shop
{
private static IShopService _shopService;
public Shop(IShopService shopService)
{
_shopService = shopService;
}
public Product GetProduct(string productId)
{
Product product = _shopService.GetProduct(productId);
return product;
}
}
[TestClass]
public class ShopTests
{
Mock<IShopService> _mockShopService;
[TestInitialize]
public void Setup()
{
_mockShopService = new Mock<IShopService>();
}
[TestMethod]
public void ShopService_GetProduct_Returns_null()
{
//Arrange
Shop shop = new Shop(_mockShopService.Object);
//This is how we return null --- all other code above is to bring this line of code home
_mockShopService.Setup(x => x.GetProduct(It.IsAny<string>())).Returns(() => null);
//Act
var actual = shop.GetProduct(It.IsAny<string>());
//Assert
Assert.IsNull(actual);
}
}
To mock a result value you can do simply:
mock.Setup(foo => foo.SomeFunctionReturningBool()).Returns(true); // or false :)
for the other question, just pass null in the unit test instead of passing mock.object and your unit test cover that too. So you basically create two unit test one with:
var actual = target.Method(mock.object);
and the other one with:
var actual = target.Method(null);
Currently your SUT is tight-coupled with MyClass implementation. You can't mock objects which are instantiated with new keyword inside your SUT. Thus you cannot test your SUT in isolation, and your test is not unit test anymore. When implementation of MyClass.SomeFunctionReturningBool will change (it will return true instead of false), tests of your SUT will fail. This shouldn't happen. Thus, delegate creation to some dependency (factory) and inject that dependency to your SUT:
[Test]
public void ShouldReturnTrueWhenMyClassIsNotNull()
{
Mock<IMyClassFactory> factory = new Mock<IMyClassFactory>();
Mock<IMyClass> myClass = new Mock<IMyClass>();
var foo = new Foo(factory.Object);
Assert.True(foo.Method(myClass.Object));
}
[Test]
public void ShouldCreateNewMyClassAndReturnSomeFunctionValue()
{
bool expected = true;
Mock<IMyClass> myClass = new Mock<IMyClass>();
myClass.Setup(mc => mc.SomeFunctionReturningBool()).Returns(expected);
Mock<IMyClassFactory> factory = new Mock<IMyClassFactory>();
factory.Setup(f => f.CreateMyClass()).Returns(myClass.Object);
var foo = new Foo(factory.Object);
Assert.That(foo.Method(null), Is.EqualTo(expected));
factory.VerifyAll();
myClass.VerifyAll();
}
BTW assignment new value to method parameter does not affect reference which you passed to method.
Implementation:
public class Foo
{
private IMyClassFactory _factory;
public Foo(IMyClassFactory factory)
{
_factory = factory;
}
public bool Method(IMyClass myObj)
{
if (myObj != null)
return true;
return _factory.CreateMyClass().SomeFunctionReturningBool();
}
}
You can use TestFixture with parameter. this test will run two times and different type value.
using NUnit.Framework;
namespace Project.Tests
{
[TestFixture(1)]
[TestFixture(2)]
public class MyTest
{
private int _intType;
public MyTest(int type)
{
_intType = type;
}
[SetUp]
public void Setup()
{
if (_intType==1)
{
//Mock Return false
}
else
{
//Mock Return Value
}
}
}
}

Rhinomocks - Mocking delegates

public interface IServiceInvoker
{
R InvokeService<T, R>(Func<T, R> invokeHandler) where T : class;
}
public class MediaController : Controller
{
private IServiceInvoker _serviceInvoker;
public MediaController(IServiceInvoker serviceInvoker)
{
_serviceInvoker = serviceInvoker;
}
public JsonResult GetAllMedia()
{
var media = _serviceInvoker.InvokeService<IMediaService, List<MediaBase>>(proxy => proxy.GetAllMediaInJson());
JsonResult jsonResult = new JsonResult();
jsonResult.Data = media;
jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return jsonResult;
}
[TestClass]
public class MediaControllerTests
{
[TestMethod]
public void GetAllMedia()
{
JsonResult data;
var serviceInvoker = MockRepository.GenerateStub<IServiceInvoker>();
var media = CreateSeveralMedia();
serviceInvoker.Stub(c => c.InvokeService<IMediaService, List<MediaBase>>(p => p.GetAllMediaInJson())).Return(media);
data = new MediaController(serviceInvoker).GetAllMedia();
serviceInvoker.VerifyAllExpectations();
Assert.IsNotNull(data);
}
}
I am stubbing the service and returning a collection. When I run this test, media is null. Any idea, how can I set expectations on this mock ?
Just found a solution. It seems to be a little ugly, but it is the first iteration only probably more elegant version will appear soon. The idea is to create another stub and match Func<> against it:
I will provide code for my use case:
[Theory]
[InlineData(342, 31129, 3456)]
public void should_call_service_invoker_and_return_result(int number1, int number2, int expected)
{
var calculator = MockRepository.GenerateStub<ICalculator>();
calculator.Stub(_ => _.Add(number1, number2)).Return(expected);
var serviceInvoker = MockRepository.GenerateStub<ServiceInvoker<ICalculator>>();
serviceInvoker
.Stub(_ => _.Invoke(Arg<Func<ICalculator, int>>.Matches(d => d(calculator) == calculator.Add(number1, number2))))
.Return(expected);
var serviceConsumer = new ServiceConsumer(serviceInvoker);
var actual = serviceConsumer.GetAddResultFor(number1, number2);
Assert.Equal(expected, actual);
}
xUnit + extensions is used as testing framework. Please ignore Theory and InlineData stuff -- it is just another way to get rid of unnecessary test setup.
Here is the code of SUT:
public class ServiceConsumer
{
private readonly ServiceInvoker<ICalculator> serviceInvoker;
public ServiceConsumer(ServiceInvoker<ICalculator> serviceInvoker)
{
this.serviceInvoker = serviceInvoker;
}
public int GetAddResultFor(int number1, int number2)
{
return serviceInvoker.Invoke(_ => _.Add(number1, number2));
}
}
public class ServiceInvoker<T>
{
public virtual R Invoke<R>(Func<T, R> func)
{
throw new NotImplementedException();
}
}
public interface ICalculator
{
int Add(int number1, int number2);
}
Hope this will be helpful. Any suggestions of how to add more beauty are welcome :)
The lambda in your unit test compiles into a class-level method (a method inside your unit test). Inside your controller, a different lambda compiles into a class-level method (inside the controller). The stub set up in your unit test doesn't match the stub being executed in your controller, so Rhino Mocks returns a default (null). More here: http://groups.google.com/group/rhinomocks/browse_frm/thread/a33b165c16fc48ee?tvc=1

RhinoMocks: how to test if method was called when using PartialMock

I have a clas that is something like this
public class MyClass
{
public virtual string MethodA(Command cmd)
{ //some code here}
public void MethodB(SomeType obj)
{
// do some work
MethodA(command);
}
}
I mocked MyClass as PartialMock (mocks.PartialMock<MyClass>) and I setup expectation for MethodA
var cmd = new Command();
//set the cmd to expected state
Expect.Call(MyClass.MethodA(cmd)).Repeat.Once();
Problem is that MethodB calls actual implementation of MethodA instead of mocking it up. I must be doing something wrong (not very experienced with RhinoMocks). How do I force it to mock MetdhodA?
Here is the actual code:
var cmd = new SetBaseProductCoInsuranceCommand();
cmd.BaseProduct = planBaseProduct;
var insuredType = mocks.DynamicMock<InsuredType>();
Expect.Call(insuredType.Code).Return(InsuredTypeCode.AllInsureds);
cmd.Values.Add(new SetBaseProductCoInsuranceCommand.CoInsuranceValues()
{
CoInsurancePercent = 0,
InsuredType = insuredType,
PolicySupplierType = ppProvider
});
Expect.Call(() => service.SetCoInsurancePercentages(cmd)).Repeat.Once();
mocks.ReplayAll();
//act
service.DefaultCoInsurancesFor(planBaseProduct);
//assert
service.AssertWasCalled(x => x.SetCoInsurancePercentages(cmd),x=>x.Repeat.Once());
I've tried to reproduce this issue, and it seems to work fine, what is different between my test code (below) and yours?
public class MyClass
{
public virtual string MethodA(object cmd)
{
return "implementation";
}
public string MethodB(object obj)
{
// do some work
return MethodA(obj);
}
}
[TestFixture]
public class MyClassTests
{
[Test]
public void MockTest()
{
var myClassMock = MockRepository.GenerateMock<MyClass>();
myClassMock.Expect(x => x.MethodA("x")).Return("mock");
Assert.AreEqual("mock", myClassMock.MethodB("x"));
myClassMock.VerifyAllExpectations();
}
}
The issue here seems to be that while in your comments you said PartialMock, but in your code sample you use DynamicMock. I believe this is the source of your issues, as they behave differently.

Categories

Resources