Is there a way to test private/ protected methods in JUnit5?
In JUnit 4 testing private methods may be an indication that those methods should be moved into another class to promote reusability. And for protected methods tests should be placed in the same package as the classes under test.
What is the case in JUnit5?
In JUnit 4 testing private methods may be an indication that those methods should be moved into another class to promote reusability.
I’d argue that this statement holds without the first three words. There’s no difference between JUnit 4 and 5 in this regard; even more, the testing framework has nothing to do with it at all.
So I recommend that you proceed equally: Either test the private method indirectly through the public interface or extract it to a place where it can be exercised independently.
Related
I'm trying to figure out whether it's an API design flaw, it is actually OK, or the SRP is being violated.
I have 2 public methods initialize() and onListRefresh(). Both of them call the same private method updateList(). The only difference between both of them is that initialize() also check for a null argument to throw an exception.
The issue is that in order to test both public methods, I practically have to copy and paste the same mocks, stub, expectations and assertions, which are all for what happens on the private method, and it feels wrong. So which one is it:
Is there a flaw in the public API design?
It's all right, that's how it's supposed to be.
SRP is being violated by using initialize() to do both checking for an argument AND calling updateList()
I'd go with 2, and stick with the parallel tests. But here's something that may be calling to you from the test code: Extract helper methods.
This can happen anywhere in the Arrange, Act, Assert phases of the tests. You may extract helpers in all 3 phases. The trick is good names, so that the tests express, simply and legibly, what they are there for.
I am not sure if what i am doing is actually the "correct" way of doing unit tests with DI. Right now i ask my ViewModelLocator to actually create all the instances i need, and just get the instance i need to test, which makes it very simple to test a single instance because lets asume that Receipt needs a Reseller object to be created, reseller needs a User object to be created, user need some other object to be created, which creates a chain of objects to create just to test one single instance.
With di usally interfaces will get mocked and parsed to the object which you would like to create, but how about simple Entities/ViewModels?
Whats the best practice to do unit testing with DI involved?
public class JournalTest
{
private ReceiptViewModel receipt;
private ViewModelLocator locator;
[SetUp]
public void SetUp()
{
locator = new ViewModelLocator();
receipt = SimpleIoc.Default.GetInstance<ReceiptViewModel>();
}
[TearDown]
[Test]
public void CheckAndCreateNewJournal_Should_Always_Create_New_Journal()
{
receipt.Sale.Journal = null;
receipt.Sale.CheckAndCreateNewJournal();
Assert.NotNull(receipt.Sale.Journal);
}
}
First, you aren't using Dependency Injection in your code. What you have there is called Service Locator (Service Locators create a tight coupling to the IoC/Service Locator and makes it hard to test).
And yes, it's bad (both Service Locator and Dependency Injection), because it means: You are not doing a UnitTest, you are doing an integration Test.
In your case the ReceiptViewModel will not be tested alone, but your test also tests the dependencies of ReceiptViewModel (i.e. Repository, Services injected etc.). This is called an integration test.
A UnitTest has to test only the class in question and no dependencies. You can achieve this either by stubs (dummy implementation of your dependencies, assuming you have used interfaces as dependencies) or using mocks (with a Mock framework like Moq).
Which is easier/better as you don't have to implement the whole class, but just have to setup mocks for the methods you know that will be required for your test case.
As an additional note, entities you'll got to create yourself. Depending on your UnitTest framework, there may be data driven tests (via Attributes on the test method) or you just create them in code, or if you have models/entities used in many classes, create a helper method for it.
View Models shouldn't be injected into constructor (at least avoided), as it couples them tightly
Units tests should run quickly and should be deterministic. That means you have to mock/stub everything that brokes these two rules.
The best way to mock/stub dependancies is to inject them. In the production, classes are assembled by DI framework, but in unit tests you should assemble them manually and inject mocks where needed.
There is also a classic unit test approach where you stub/mock every dependency of your class, but it's useless since you don't gain anything by that.
Martin Fowler wrote great article about that: link
You should also read Growing Object-oriented software: Guided by tests. Ton of useful knowledge.
I have looked at other discussions about this topic (on StackOverflow) however the other questions seem to be language specific whereas this is not language specific and I'm considering no longer using private methods, classes, and modules.
I want to test my private methods, classes, and modules so that I can more easily locate bugs. To allow me to do this I'm considering no longer using private methods, classes, and modules for two reasons, (1) I see no reasonable way of testing a private method, class, or module without injecting test code or using some sort of "magic" and (2) to improve code reuse. Note that I'm not considering no longer using private variables and properties because data needs protecting and does not provide behaviour therefore it does not need to be public during testing.
As a lame example, if you're writing a module called OneOperations that has two public methods addOne and subtractOne, and two private methods add and subtract. If you were not allowing yourself to have private methods you would put the two private methods into another module (basicOperations) where they are public and import those methods inside the OneOperations module. From this you should now be able to write testing code for all the methods in both modules without injecting code. An advantage of this is that the methods add and subtract can now be used in other modules by importing the basicOperations module (2 - improving code reuse).
I have a feeling this a bad idea, but I lack the real world experience to justify not doing this, which is why I've posted this question on StackOverflow.
So, how do you test your private methods, classes, and modules? Is not writing private methods, modules, and classes a potential solution?
1) Like in many other answers on this topic, the main question is why would you want to test your private methods? The purpose of a class is to provide some functionality to its clients. If you have comprehensive unit tests that prove that the public interface of this class behaves correctly, why do you care what it's doing in its private methods?
2) Your idea of not having private methods at all seems like cutting your leg off. For small projects it may be possible to have every tiny behaviour well separated and tested. But for large projects it's an overkill. What matters, is the domain logic behaving correctly.
Consider for example a method:
public double getDistanceSquared(Point other)
{
return getDifferenceSquared(this.x, other.x)
+ getDifferenceSquared(this.y, other.y);
}
private double getDifferenceSquared(double v1, double v2)
{
return (v1 - v2)*(v1 - v2);
}
Ad1) Does it really make sense to unit test getDifferenceSquared method, if getDistanceSquared returns correct results for all test cases?
Ad2) Creating a separate class for calculating squared distance between doubles - in case there is only one place when it'll be used leads to a swarm of tiny classes, with millions of tests. Also, constructors of your domain classes will accept like 10 different interfaces for every tiny thing they're doing internally.
Maintaining all this is a lot of unnecessary work. Imagine that you would like to change the method of calculating the distance (maybe use some precomputed values). The behaviour of getDistanceSquared would not change. But you would have to change all of the tests of getDifferenceSquared even though you shouldn't have to care how is the distance being calculated, as long as it's calculated correctly.
Diving into minor details when it's not necessary makes you forgot what you're really doing - you lose the "big picture view". Value your time, and focus on important problems.
As a side note, also - the main concern of unit tests is not "locating bugs" as you suggest. They impose a clean design, provide an always up-to-date documentation of your code's behaviour and allow convenient refactoring giving you flexibility. Additionally they assure you that the code is working as you expect it to.
http://artofunittesting.com/definition-of-a-unit-test/
http://en.wikipedia.org/wiki/Unit_testing#Benefits
There is another way to look at this, which is how do you generate a private method?
If we are following the TDD process properly, then the first thing we write is the test. At this point the test should contain all of our code, e.g.
public void ShouldAddTwoNumbers()
{
(1 + 1).ShouldEqual(2);
}
Yes, that looks appalling. But consider what happens as we write is some more tests.
public void ShouldAddTwoMoreNumbers()
{
(2 + 2).ShouldEqual(4);
}
Now we have something to reactor, so it can become
public void ShouldAddTwoNumbers()
{
Add(1, 1).ShouldEqual(2);
}
public void ShouldAddTwoMoreNumbers()
{
Add(2, 2).ShouldEqual(4);
}
private int Add(int a, int b)
{
return a+b;
}
So now we have a private method that we can test inside our test class. It's only when you complete further refactoring to move the code out into your application, that the private becomes an issue. Most automated refactoring tools will offer you the option of changing the methods signature at this point, so that the private method is still accessible, because its not private.
(There is a fabulous exercise called TDD as if you mean it by Keith Braithwaite which I've just paraphrased above)
However, this isn't the end of our refactorings and development. One thing that we should be doing as we write and refactor our tests is to delete old tests, for example when functionality is duplicated. Another is to extract new methods so we don't repeat ourselves. Both of these can lead to scenarios where we have private methods back in the non-test code base.
So my advice is to be pragmatic, make the best decision you can for the code that you have in front of you. I wouldn't advise not creating private methods, but I would instead look at the factors that lead you to create them.
I know it may sound like a silly question as I've heard many saying that you should only do unit testing for public function and indeed, visual basic.net in Visual studio IDE only allows me to do unit testing for public function.
However, I got a public function that is calling to many other private functions.
If I do unit testing for that public function, that would be too complicated. I only want to test each private function individually to make sure it works correctly first, before jumping to the parent public function.
One solution I've had in my mind is that I could change all private functions to public ones so that Visual Studio allows me to do unit testing for them. But it is annoying me as I don't want them to be public.
Is there any suggestions you could let me know please?
many thanks in advance.
N.T.C
If you really can't break the code out into separate classes, you could change all of the private functions to be protected and then create a private class within your test class that inherits from the class you're trying to test (this would be named as a fake or stub, hence my advice to make it private. You don't want code outside of the test class to interact with this). Within your inherited class, create public functions for each of the now protected functions that simply call through to the base and write your unit tests against those instead.
I apologize if this capability is not available in VB:
Create a sub-class of the class you want to test. Ensure that the sub-class has public interfaces to the private functions.
As for "only unit test public functions?" That's horse manure. You test what might fail. For instance, you might have a class with only one public function, and you want to refactor into a set of calls on private functions to decrease the complexity. If you have to refactor your solution for any reason (as one of the comments suggested), then the first step is to have all the pieces of the solution tested that you will have to change during the refactoring.
In my src, there exist a class which contains a method
public static boolean doExtensionsMatch(String s, String t) {
There is nothing wrong with it, except that there is no need for it to be public. It is used inside the class where it is declared.
It is public however, since some time ago, i felt this method needed to be tested directly and thus, private visibility did not work for me.
At this point:
I'd rather not throw away those tests. If i make the method private however, tests will become unusable.
I would rather for tests to remain in it's current src-test folder, thus maintaining separate locations for source and tests
So, you tell me, what should i do?
Should i change the method to private and delete the tests?
You test interface to prove that class behaves as it should.
So private methods don't need to be tested as long as they aren't accessible. And even more - you shouldn't care of how interface does its work, you should be fine with just the results.
You test the behaviour, not the implementation.
I would suggest using partial classes. If your test classes are partial classes of the class to be tested they will have access to all methods and variables whether or not they are public.