Skip to main content

Unit Testing Critical Legacy Code

I once worked on a medical project which required intense Unit Testing in C#. A problem I encountered is that all of the critical sections of the code can't be accessed or required a massive amount of object dependencies. The dilemma I was in drove me to search for a new soluion. Good thing I found TypeMock Isolator.

TypeMock Isolator is a mocking framework that can take control of function calls regardless if it is accessible or not such as privately declared functions and etc. This Framework is center-focused on white box testing legacy code; although, can be used for black box testing.

Why use it?

  • Code not Written using SOLID Principles
  • Tested code is not following TDD(Test Driven Development)
  • Testing legacy code
  • Unrefactorable tested code
  • Excellent for mission critical code.

Mock Instantiation

Using Typemock Isolator, object instantiations can be ignored.
  • Ignore Constructor
ClassToTest obj = Isolate.Fake.Instance<ClassToTest> (Members.CallOriginal, ConstructorWillBe.Ignored);
  • Ignore Base Class
ClassToTest obj = Isolate.Fake.Instance<ClassToTest> (Members.CallOriginal, ConstructorWillBe.Ignored, BaseConstructorWillBe.Ignored);

Mock Behaviour

A powerful feature of this framework is its ability to switch out function calls regardless of its access modifier.
  • Non-Public Method
Isolate.NonPublic.WasCalled(objectToTest, "PrivateMethod" ).DoInstead(context => { /*Substitute Method */});
    "context" can be use to :
        1.) Get method’s instance
        2.) Get/Set arguments
  • Public Method
Isolate.WasCalled(objectToTest, "PublicMethod").WillReturn(VALUE);
  • Properties
Isolate.NonPublic.Property.WhenSetCalled(objectToTest,"Property").Doinstead(context => {/* Do Something */});

Invoke!

Another useful feature is being able to Invoke inaccessible functions so it can be tested.
  • Invoke NonPublic methods
Isolate.Invoke.Method(objectToTest, "PrivateMethod"), new object[] {Argument});
  • Fire events
Isolate.Invoke.Event(() => {eventTested += null;}, new object[]{Argument});

Example 1

This example shows that private functions can be invoked and tested without having to care about dependencies in constructor.

Code to Test


Unit Test


Example 2

This example shows that you don't have to think about dependencies on the function calls inside your unit on test. In this case, Coolness function's behaviour is being swaped by a dummy lambda function.

Code to Test

Unit Test

Example 3

Lastly, let us look into this really interesting test problem. Some critical systems will definitely need to have some variables set to a certain value to operate correctly. In the constructor, in the middle of operation, _hunger needs to be in a certain value before and after SearchFood() function. Normally, this is almost impossible to do. We can test SearchFood() function as a hook to extract the current state of _hunger.

Code to Test

Unit Test

Conclusion

If you are stuck in a similar dilemma as I did wherein  I could not access anything, Here is the solution to the problem! This framework can save you lots and lots of time.

Here is the official website of Typmock

Comments

Popular posts from this blog

Getting Used to tmux!

This is a short guide to multiplexing in your terminal! Installation Install  $ sudo apt install tmux launch $ tmux Core Commands Here is a small list of the most useful set of commands. Just remember these and you shall be tmuxing around in no time! Adding panes Add panes vertically ctl + b % Add panes Horizontally ctl + b "  Moving around panes Move to the panes to the right ctl + b <Right> Move to the panes to the left ctl + b <LEFT> Move to the panes to the up ctl + b <UP> Move to the panes to the down ctl + b <DOWN> Closing Window  Close current panes ctl + d Tip!!! You can resize panes by pressing: $ ctl + b + <arrow button> Scroll: $ ctl + b [ press < UP > or < DOWN > Quit $ q  

Installing Qt Cross Compilation Toolchain for Beaglebone Black

This is the guide that I went through to successfully set the environment. If you get stuck on something, feel free to have a look at the references in the bottom most. These are the steps that worked for me so I hope it helps. Just making sure of the dependencies sudo apt-get update sudo apt-get upgrade sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0 libstdc++6:i386 ia32-libs Assuming that you can get access to the root Set up Cross compiler Download and install wget -c https://releases.linaro.org/components/toolchain/binaries/6.4-2018.05/arm-linux-gnueabihf/gcc-linaro-6.4.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz tar xf gcc-linaro-6.4.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz export CC=`pwd`/gcc-linaro-6.4.1-2018.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- Test installation ${CC}gcc --version Download qt source #do this in a directory that is not in your root filesystem, i.e. ~ git clone git://code.qt.io

Force Deleting Contents in Rubbish Bin - Ubuntu

You may have deleted some files when you are in super user mode (sudo). The problem here is that when you are using uvunru variants, you can't empty the rubbish bin since the files transported where from a sudo operation. you can't also open the rubbush bin folder even if you opened the file browser through sudo. So to get around this, we erase is through terminal!!! We navigate through the rubbish bin folder through terminal and delete all the contents through the "rm" command. $ sudo rm -rf  ~/.local/share/Trash/files/*