Unit testing with Moq

Let's say I have a simple class with several functions:

public class MyClass { public int GetTotal(int myValue, string myString) { if (myValue > 10) return GetTotal(myValue); else return GetTotal(myString); } public int GetTotal(int myValue) { return myValue * 25 / 12 + 156; } public int GetTotal(string myString) { return myString.Length * 25 / 48 + 27; } } 

I would like to unit test to execute my first function and "make fun" of the rest, int GetTotal(int myValue) and int GetTotal(string myString) , to check only the code inside the main function. I use Moq as a mocking structure. Are there any tricks that would allow me to get the code from the function I want to test and make fun of the internal call for other functions? Or do I need to call a second object like this in order to mock everything?

 public class MyCalculator { public int GetTotal(int myValue) { return myValue * 25 / 12 + 156; } public int GetTotal(string myString) { return myString.Length * 25 / 48 + 27; } } public class MyClass { MyCalculator _Calculator; public MyClass(MyCalculator calculator) { _Calculator = calculator; } public int GetTotal(int myValue, string myString) { if (myValue > 10) return _Calculator.GetTotal(myValue); else return _Calculator.GetTotal(myString); } } 

I know that the latter is the cleanest way, but I have many functions calling themselves one by one so that there are many classes for writing.

Update

Layout implementation of Thomas answer:

 public class MyClass { public int GetTotal(int myValue, string myString) { if (myValue > 10) return GetTotal(myValue); else return GetTotal(myString); } public virtual int GetTotal(int myValue) { return myValue * 25 / 12 + 156; } public virtual int GetTotal(string myString) { return myString.Length * 25 / 48 + 27; } } [TestClass] public class Test { [TestMethod] public void MyClass_GetTotal() { Mock<MyClass> myMockedClass = new Mock<MyClass>() {CallBase = true}; myMockedClass.Setup(x => x.GetTotal(It.IsAny<int>())).Returns(1); myMockedClass.Setup(x => x.GetTotal(It.IsAny<string>())).Returns(2); var actual = myMockedClass.Object.GetTotal(0,string.Empty); Assert.AreEqual(2,actual); } } 

Update 2

See Guiche's answer also for a more global view of this "problem."

+6
source share
2 answers

Of course! In Rhino Mocks, you can use a partial layout for this purpose. Create a new layout like this:

 var mock = MockRepository.GeneratePartialMock<MyClass>(); 

You can then make fun or stifle these two methods that you do not want to call like this:

 mock.Stub(x => x.GetTotal(10)).Return(42); 

This requires your GetTotal methods to be virtual, though.

+3
source

You use bullying to distract unpleasant addictions. Therefore, if your class deals with files, networks, things that are difficult to control / feel, you distract them from the role / interface. This allows you to falsify / mock this role (isolate your tests from unfair real implementation / dependency on the test).

So if A depends on B and B, it’s hard to control / understand OR just slowly. We put B on the role of R, and then mock R for unit testing A.

In your case, your A.Method1 internally calls Method2 or Method3, which I believe is not dishonest. Insulating M1 from M2 and M3 is too much cost for the small benefit of IMHO (unless I understand some contextual details). If tomorrow you decide to reorganize Method1 to use M4 instead of M3, your tests will fail, even if M1 does what it should do (from pov functionality)

You can directly write tests against Method1 without letting the tests know the implementation details (which it calls M2 and M3). So my commentary was an insulating object useful from time to time. But isolating the functions of the same object from each other is excessive IMHO.

+2
source

Source: https://habr.com/ru/post/889931/


All Articles