Lecture thumbnail 0:00 / 0:00 So we’re going to take a look at some of the problems with the singleton, namely the testability problem.

But before we do that, I want to actually start writing tests.

And the first test that I want to write is a test which ensures that our singleton is in fact a singleton.

So I’ve already got an N unit reference added to this particular project via a nugget package.

And I also got a couple of other things added like Autofac, which we’re going to need in the next clip.

So what I’m going to do is I’m going to write a test to make sure that the number of instances we have

is one and that any new instance that we get refers to that same object.

So to do this, let’s make a class called singleton tests.

I’ll decorate it with the test fixture attribute.

And then of course, I’ll make a test.

Let’s call it is singleton test.

So once again, mark it with the test attribute here.

So what I’m going to do is get two instances of the database and I’m going to compare them to make sure

that they are referentially equal.

And in addition, I’ll do some way of calculating the number of instances that have been created.

So the way this is done is as follows.

So I’ll say var DB equals singleton database instance, and then I’ll make DB two, which will do the

same thing.

And then my first assertion will be that DB is the same as DB two.

So in N unit is the same as basically checks for referential equality, basically checks that the two

instances referenced the same object.

So now the second thing I want to do is to calculate the number of instantiations.

And this can be done using a static variable, for example.

So that’s what we’re going to do here.

So I’m going to stick a well, I’ll have a private static int instance, count here zero by default,

and then of course I’ll expose it as a public property.

So I’ll have public static int count, returning instance, count like so.

Now I’m simply going to increment this count right inside the constructor.

So I’ll say instance count plus plus and it will take a look at this variable because this gives us

an indication of how many times the constructor was actually called.

So coming down here, what I can do is I can assert that Singleton Singleton database dot count is equal

to one because we only need one instance to be initialized.

So having made this, we can build and then we can run this particular test.

So let’s just do it and see whether it passes.

Okay, So we do have a bit of a problem and that problem is with accessing capitals.

Dot txt because remember when the tests are run in resharper or anywhere else, they don’t change the

default directory.

So what this implies is that instead of reading capitals dot txt, we need to adjust our code a little

bit.

So I’m going to basically just replace it with something like this.

So here what I’m doing is I’m grabbing the assembly location directory and then I’m appending capitals

dot txt here, like so.

So this is a more safe way and we can now once again, I’m going to build this and we can now run the

test again and hopefully this time around it passes.

All right, so we now have a successful singleton and now we’re going to take a look at the actual problems

with the singleton.

Now, let’s suppose that we have some component which actually consumes a singleton.

We have a component which needs a database to work with.

So, for example, let’s suppose that we have a component which calculates the total population of a

given number of cities.

So I’m going to call it a singleton record finder.

So Singleton Record finder finder like so.

Okay.

So the idea here is that we have a public int total population actually, let’s go with get total population.

So this is a method which given a number of names, it returns you the total population in all of these

cities combined.

So I have enumerable of string names and then of course the implementation is very easy because you

just have result as zero and then for each of the names, so for each of our name in names, what you

do is you grab the Singleton database and unfortunately we are stuck to calling it via the Singleton

interface.

So we say result plus equals, and then we take singleton database, dot instance, dot get population

for the given name and then we return result.

Okay, so having this component, this singleton racket finder, we can now write a test on this racket

finder.

So instead of testing the database directly, we are testing somebody that uses a database.

So I’m going to make a test called Singleton Total Population test.

Okay.

So that will also have a test attribute here.

And what I’m going to do is I’m going to make a racket finder.

So that’s going to be a new singleton.

Singleton racket finder like so.

And then.

I’ll make a bunch of names for the cities whose total population I want.

So that may be so.

As well as México City.

Mexico City.

There we go.

Okay, so having these two names, what I can do is I can grab the total population and TP is equal

to RF dot total population.

Get total population.

I’ll provide the names and then I can assert that TP is equal to.

And at this point, unfortunately, if I want to have the calculation done correctly, I would have

to go into the txt file into capitals, dot txt and look up the populations for the appropriate cities.

So that would be zero and Mexico City.

So that’s 17.5 and 17.4 million.

So I would have to go into the database and I would have to paste the data here.

So 1.75.

Dum dum dum dum dum.

Plus 174.

Dum dum, dum, dum, dum, dum dum.

There we go.

So this is the expected values.

And once again, we can compile the project and then run this particular test and see whether it passes

or not.

Hopefully it does.

So everything is okay for now, except for the fact that you are testing on a live database and you

can already see some of the consequences of this.

I’ve had to look up items in the database and let’s suppose somebody goes into the database and they

remove Mexico City.

Then not only is, you know, well, the problem with that is that my test now doesn’t work because

we’re not going to find Mexico City anymore.

So being dependent on a live database that costs a lot of resources to actually access is a bad idea.

You really want to fake the entire database, You want to fake object instead of the real database,

but you cannot get it.

And the reason why you cannot get it is because the record finder that you’re using has a hard coded

reference to the instance.

So this is the problem with the singleton that once you start using the singleton everywhere, your

hard coding, a reference to the instance of that particular component.

And so you cannot really substitute this with something else.

So in the next clip, we’re going to see how we can actually solve this problem.

Play Play Stop Play Play Play Play Start Play information alert