Tag Archives: Action

Introduction to Unit Tests (with examples in .Net) – Part 2 – Refactoring and Mocking

This forms the second in a short series of posts on unit tests. You can find the first post in this series here.

In this post, I’ll be expanding the points raised in the first post to cover a slightly more realistic scenario, and offering some tips of how re-factoring might help with the creation of unit tests. We’ll also cover the basic principles behind mocking – I’m intending to cover this in more detail in a future post of this series.

A Quick Recap

You’re welcome (and encouraged) to go back to the first post in the series; however, to summarise, we discussed the Arrange/Act/Assert pattern, and how it can help us structure a unit test; we spoke about the FIRST principles of testing, and thereby the attributes that we should look for in a good unit test.

What we specifically didn’t cover was any testing frameworks, the concept of mocking or any mocking frameworks, or how to write a unit test in a scenario where you’re not simply adding two numbers together.

A More Realistic Unit Test

If we take an example of any level of complexity, we might question some of the points that were made in the first post. After all, very few methods would simply take two numbers and add them together – or, if they do, perhaps we need to reconsider the language that we’re using.

Let’s look at a simple console application:

int myNumber = Random.Shared.Next(100) + 1;

Console.WriteLine("Guess the number that I'm thinking between 1 - 100");
var guess = Console.ReadLine();
if (string.IsNullOrEmpty(guess))
{
    Console.WriteLine("Invalid guess");
    return;
}

if (int.Parse(guess) == myNumber)
{
    Console.WriteLine("Well done, you guessed!");
}
else
{
    Console.WriteLine($"Sorry, that was the wrong number, I was thinking of {myNumber}");
}

If you had to test this code, how would you do it?

In fact, it’s really difficult, because every time you run it, the number is different. This is a simple piece of code, there’s only 3 code paths; arguably, your strategy could be: run it once and enter a blank value, run it once and enter a non-numeric value, run it 100 more times and hope that you’ll get the number right once.

Writing a Test

As before, let’s start with the manual test that we’ve just described; arguably, we could simply automate this. We’d probably do something like this:

        public static void RunTest()
        {
            // Run method here - check that a blank entry works

            // Run method here - check that a numeric entry works

            for (int i = 0 ; i < 100; i++)
            {
                // Run method here - exit this loop once we've determined that we have a correct and incorrect guess

            }
        }

In fact, running that exact test would be possible – we could simply redirect the console input and output; however, for the purposes of this post, we’ll bypass that method (as it is quite specific to writing a .Net Console app), and we’ll re-factor our code a little.

Refactoring

We can refactor it by splitting the method into two; one method that accepts the input, and one that runs the business logic:

void RunMethod()
{
    int myNumber = Random.Shared.Next(100) + 1;

    Console.WriteLine("Guess the number that I'm thinking between 1 - 100");
    var guess = Console.ReadLine();
    BusinessLogic(myNumber, guess);
}

void BusinessLogic(int myNumber, string guessedNumber)
{
    if (string.IsNullOrEmpty(guessedNumber))
    {
        Console.WriteLine("Invalid guess");
        return;
    }

    if (int.Parse(guessedNumber) == myNumber)
    {
        Console.WriteLine("Well done, you guessed!");
    }
    else
    {
        Console.WriteLine($"Sorry, that was the wrong number, I was thinking of {myNumber}");
    }
}

All we’ve done here is split the method into two methods – the code is exactly the same as it was before. However, now we can run the code in our test without worrying about the input:

        public static void RunTest()
        {
            // Check that a blank entry works
            BusinessLogic(3, "");

            // Check that a non-numeric entry works
            BusinessLogic(3, "aardvark");

            for (int i = 1; i <= 100; i++)
            {
                // Check that false and true numbers work
                BusinessLogic(i, "2");
            }
        }

It still feels a lot like we’re only testing half of the code. We aren’t testing the calling method.

Mocking

Let’s refactor a little further. Instead of using the console, we’ll simply create our own method that performs the same task:

private static string? GetInput() => Console.ReadLine();    

Again, no real change here, we’re just wrapping the code that accepts input in a method that we control.

Now that we’ve done this, we can use our own method to accept input, instead of the Console methods. There’s a number of ways we could do this but, perhaps the easiest, is to pass the GetInput method into the RunMethod method as a parameter:

public static void RunMethod(Func<string> readData)
    {

        int myNumber = Random.Shared.Next(100) + 1;

        Console.WriteLine("Guess the number that I'm thinking between 1 - 100");
        string? guess = readData();
. . .

Here, we’re simply changing two things: we’re accepting a delegate into our main method, and then we’re calling that, instead of the Console.ReadLine().

What’s the point of doing that? Well, now that we control that function as a parameter, we can mock the function, and replace it with our own functionality.

In fact, we are not technically discussing a mock here, but a stub. For the purpose of this post, we’ll simply group them together with the working definition that a mock is: “anything that replaces functionality for the purpose of testing”. I intend to re-visit this in a future post and go into more detail on the difference between the two.

Let’s jump to our test.

Arrange

In the test, we can now replace this functionality with a specific value:

        public static void RunTest()
        {
             // Arrange
            Func<string> mockInput = () => "5"; . . .

We’ve now established the input of the method, the next step is to be able to assert that the test worked. In fact, that’s very difficult with the code as it currently is, because we just display output to the user. To finish this post off, we’ll refactor this as little as we can; imagine we take the business logic function and change it to be like this:

string BusinessLogic(int myNumber, string guessedNumber)
{
    if (string.IsNullOrEmpty(guessedNumber))
    {        
        return "Invalid guess";
    }

    if (int.Parse(guessedNumber) == myNumber)
    {
        return "Well done, you guessed!";
    }
    else
    {
        return $"Sorry, that was the wrong number, I was thinking of {myNumber}";
    }
}

All we’ve changed here is that we’re returning the string, instead of outputting it. We can then change the calling method to do the output:

string RunMethod(Func<string> readData)
{
    int myNumber = Random.Shared.Next(100) + 1;

    Console.WriteLine("Guess the number that I'm thinking between 1 - 100");
    string? guess = readData();
    string result = BusinessLogic(myNumber, guess);
    Console.WriteLine(result);
    return result;
}

Same idea again, a very small change of writing the output, and returning the result again. The functionality hasn’t changed, but now we have something to test against.

Assert

We can now write out test method to look something like this:

for (int i = 1; i <= 100; i++)
{
    // Arrange
    Func<string> mockInput = () => "5";

    // Act
    string result = RunMethod(mockInput);

    // Assert
    if (result == "Well done, you guessed!")
    {
        Console.WriteLine("Test Passed");
        break;
    }
}

for (int i = 1; i <= 100; i++)
{
    // Arrange
    Func<string> mockInput = () => "5";

    // Act
    string result = RunMethod(mockInput);

    // Assert
    if (result.StartsWith("Sorry, that was the wrong number"))
    {
        Console.WriteLine("Test Passed");
        break;
    }
}

{
    // Arrange
    Func<string> mockInput = () => "";

    // Act
    string result = RunMethod(mockInput);

    // Assert
    if (result == "Invalid guess")
    {
        Console.WriteLine("Test Passed");
    }
}

There’s three distinct tests here and, unless unlucky, they’ll all pass. There’s definitely some work left to do here, as we still have the following problems:

1. Although the tests can pass, we have to visually ascertain that.
2. We’re outputting to the console needlessly.
3. Our tests are not resilient – if I change a single character in the user output, the tests will break.
4. The tests are not deterministic – they are dependent on the result of a pseudo random number.

In the next post, we’ll address these issues: we’ll introduce a test framework, and further refactor this code such that we can be confident that cosmetic changes will not break the tests.

React, Redux, and Typescript – Why, What and How

This article covers adding Redux to an existing React application.

Redux is one of those technologies where you get introduced to it, and you think: this seems overly complex to solve such a simple problem. Quite often, this is, in fact, the case. I once read a post (which I cannot find) by Dan Abramov where he said a similar thing himself. Redux is a state manager, and if you’re using it for React, React does have facilities to manage its own state, so you may not need Redux.

In fact, from what I’ve seen, I’d say you’re better leaving it until you know you need Redux.

Why

So, how will you know when you need Redux?

Well, you’ll know because you’ll raise some state, and suddenly realise that you’ve raised it into a component that has no business managing that state. My specific example was trying to manage user permissions.

Imagine the following menu structure:

Layout.tsx
	NavMenu.tsx
		NavItem (React-Strap)
		LoginMenu.tsx (accesses the DB to get user info)

I needed to store a user permission, and conditionally display a menu option (NavItem); these are held in a LoginMenu component. This meant that my state would need to be in NavMenu.tsx – but that’s a strange place for the state regarding a user to live. Additionally, other parts of the application would need access to this, and so it’s time for a state manager.

What

Okay, we’ve talked about why you might want to add Redux. Let’s see, exactly what Redux is. Essentially, there are three concepts to Redux. Before I continue with my second rate explanation, I would strongly suggest you jump over to Dave Ceddia’s blog. If you’re trying to do this in Typescript, then come back afterwards – otherwise, stay there, there’s nothing I can tell you that he doesn’t cover in this article.

Actions

An action is simply an object that contains a property called type. It can contain other objects, too, and is used to send information from your application into the Redux Store.

Reducers

Reducers are the engine of Redux. They accept an action, and the existing state of the application, and they return a new state.

Store

The store holds the current application state. You cannot change this directly, but through an action.

How

(In this section, I’ll include some imports and file names – I’ll talk about project structure towards the end, and the imports and filenames will make sense then)

Let’s imagine that your application is a game, where you can move a character left and right; your application state might look like this:

export interface IStore = {
    position: 0
}

We’ll also need to create the store, which we can do in the same code file:

Store.tsx

import { reducer } from '../State/Reducer';
import { createStore } from 'redux';

export interface IStore {
    position: number;
}

const store = createStore(reducer);
export default store;

Okay, so we have a state: we said that actions are the only things that can affect state (in fact we said through an action): let’s see what an action might look like:

export const MOVE = 'MOVE'

interface MoveAction {
    type: typeof MOVE
}

This would be sufficient, at least, this is all Redux needs; however, we need to know which way to move, etc. Convention seems to be to add a payload property; let’s see what that might look like:

Actions.tsx

export const MOVE = 'MOVE'
export interface Message {
    user: string
    message: string
    timestamp: number
  }
  
interface MoveAction {
    type: typeof MOVE
    payload: Message
}
    
export type ActionTypes = MoveAction;

I’ve used a generic Message – you could make this specific to your action, but this sort of approach means that your messages are consistent across actions.

So, now we have a store (somewhere to keep the state), and an action something to indicate that we wish to update the state. However, looking at the action, it doesn’t seem to do too much updating… In fact, it’s just a message – it could even be just a string. We now need the final piece of the jig-saw: the reducer takes the action and updates the state; let’s see what that might look like:

Reducer.tsx

import { InitialState } from './Store';
import { ActionTypes, MOVE } from './Actions';

export function reducer(state = InitialState, action: ActionTypes) {  
    console.log (action);
    switch (action.type) {
      case MOVE:
        return {
            ...state,
            position: state.position + parseInt(action.payload.message)
        }
        
      default:
        return state;
  
    }
    
}

There’s quite a lot here: (we’ll come back to InitialState shortly). Let’s go through a piece at a time.

The first thing we’re doing is checking the type parameter:

    switch (action.type) {
      case MOVE:

In a real world situation, there would be many options: you’re unlikely to have a single action, so the switch statement is necessary.

Remember earlier, we defined the action as MOVE:

export const MOVE = 'MOVE'

Which enables us to check for MOVE, rather than the magic string “MOVE”.

Inside the MOVE block, we’re accessing the payload:

      case MOVE:
        return {
            ...state,
            position: state.position + parseInt(action.payload.message)
        }

The reducer must be a pure function: that is, it accepts and returns data, but it does not change anything; as a result, we’re returning a new version of the state that was passed in. We’re setting the new state to have a position which is based on the current position, but we’re not changing the state.

This code will crash if the message is set to “qwerty” (so if you’re doing this sort of thing yourself, you should do it better than I have!)

Finally, the default: block simply returns the same state that it was given; i.e. the state remains unchanged.

Initial State and Project Structure

I said we’d come back to initial state. In the reducer, we have the following:

export function reducer(state = InitialState, action: ActionTypes) {  

We have to define a starting state for the store; and you can do that like this:

Store.tsx

export const InitialState: IStore = {
    position: 0
}

Before we move onto the application changes, let’s quickly talk about where this all goes. The frustrating answer is, it’s up to you; however, I found a structure like this quite useful, as it keeps all the Redux plumbing in a single place:

Plugging this into your app

So far, we’ve created a lot of code, but it’s been completely separate from your React application. Plugging it in is actually quite trivial. Let’s start with Index.tsx; you’ll need to import your reducer:

import { reducer } from './State/Reducer';

In the render function, you’ll then need to add the store into the DOM:

ReactDOM.render(
  <Provider store={store}>
    <BrowserRouter basename={baseUrl}>
      <App />
    </BrowserRouter>
  </Provider>,
  rootElement);

We can then access the store inside any component by simply referencing the Store.tsx:

import store from '../../State/Store';
import { MOVE } from '../../State/Actions';

And then calling the dispatch function:

            store.dispatch({
                type: MOVE,
                payload: {
                    user: user.name,
                    message: "1",
                    timestamp: new Date().getTime()
                }
            });

We can also get the state by using this:

store.getState();

Connecting the State

This works okay, but there is an easier way; you can use the Redux Connect function. Essentially, instead of exporting the React class, you instead export a wrapper for it. Before that, though, you need to work out what you’re trying to map. You’ll need to split your props into three groups:

1. Props from the store that you want in your component
2. Props that you want to be passed into your component
3. Props from the store that are actually functions; that is, dispatch functions

You would then rewrite your component like this:

import { connect } from 'react-redux';
interface StoreProps {
   position: number;
}
interface OwnProps {
   ...
}
interface DispatchProps {
   ...
}

type Props = OwnProps & StoreProps & DispatchProps;
interface IState {
   ...
}
class GameComponent extends Component<Props, IState> {
   ...

Notice that you’re no longer exporting the GameComponent class. Instead, you add the following:

function mapStateToProps(state: IStore) {
  return {
    position: state.position
  };
}
export default connect(mapStateToProps)(GameComponent);

This allows you to expose only the properties relevant to the component, but not the properties that you take from the Redux store.

References

https://blog.logrocket.com/why-use-redux-reasons-with-clear-examples-d21bffd5835/

https://daveceddia.com/redux-tutorial/

https://daveceddia.com/access-redux-store-outside-react/

https://redux.js.org/recipes/usage-with-typescript

Testing for Exceptions using the Arrange Act Assert Pattern in C# 7

Unit testing massively benefits from following the Arrange / Act / Assert pattern. I’ve seen tests that are not written in this way, and they can be sprawling and indecipherable, either testing many different things in series, or testing nothing at all except the .Net Framework.

I recently found an issue while trying to test for an exception being thrown, which is that Nunit (and probably other frameworks) test for an exception by accepting a delegate to test. Here’s an example:

        [Test]
        public void Test_ThrowException_ExceptionThrown()
        {
            // Arrange
            TestClass tc = new TestClass();

            // Act / Assert
            Assert.Throws(typeof(Exception), tc.ThrowException);
        }

We’re just testing a dummy class:

    public class TestClass
    {
        public void ThrowException()
        {
            throw new Exception("MyException");
        }
    }

C# 7 – Inline functions

If you look in the references at the bottom, you’ll see something more akin to this approach:

        public void Test_ThrowException_ExceptionThrown2()
        {
            // Arrange
            TestClass tc = new TestClass();

            // Act
            TestDelegate throwException = () => tc.ThrowException();            

            // Assert
            Assert.Throws(typeof(Exception), throwException);
        }

However, since C# 7, the option on a local function has arrived. The following has the same effect:

        [Test]
        public void Test_ThrowException_ExceptionThrown3()
        {
            // Arrange
            TestClass tc = new TestClass();

            // Act
            void CallThrowException()
            {
                tc.ThrowException();
            }

            // Assert
            Assert.Throws(typeof(Exception), CallThrowException);
        }

I think that I, personally, still prefer the anonymous function for this; however, the local function does present some options; for example:

        [Test]
        public void Test_ThrowException_ExceptionThrown4()
        {
            void CallThrowException()
            {
                // Arrange
                TestClass tc = new TestClass();

                // Act
                tc.ThrowException();
            }

            // Assert
            Assert.Throws(typeof(Exception), CallThrowException);
        }

Now I’m not so sure that I still prefer the anonymous function.

References

http://stackoverflow.com/questions/33897323/nunit-3-0-and-assert-throws

https://pmbanugo.wordpress.com/2014/06/16/exception-testing-pattern/

http://stackoverflow.com/questions/24070115/best-approach-towards-applying-the-arrange-act-assert-pattern-when-expecting-exc

Working with the threading system in Unity

Unity seems to have a multi-threaded system, but I could find no way of accessing the dispatcher. Consequently, it’s necessary to create some kind of self-rolled task queue. The specific problem that I faced was with using the timer; here’s the code for the timer:

public class MasterScript : MonoBehaviour
{
    private Timer _timer;

    void Start ()
    {
        _timer = new Timer();
        _timer.Interval = 1000;
        _timer.Elapsed += _timer_Elapsed;
        _timer.Start();
    }

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        SpawnNewObject();
    }
}

The idea being that every second, and new object would appear on the screen. However, as soon as you run this, it crashes (or as close as Unity comes to crashing):

FindGameObjectWithTag can only be called from the main thread

The solution that I came up with was as follows:

public class MasterScript : MonoBehaviour
{
    public static Queue<Action> TaskQueue;

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        SpawnNewObject();
    }

    private void SpawnNewObject()
    {
        TaskQueue.Enqueue(() =>
        {
            var newObj = Instantiate<GameObject>(MyObject);

Then, simply change the Update function to run them:

    void Update ()
    {
        if (TaskQueue.Count > 0)
        {
            TaskQueue.Dequeue().Invoke();
        }
    }

I’ve used the idea of a “Master Script” to deal with the queue, and this can be queued to from somewhere else in the game, which makes it more flexible.