How to test a function which calls another function when doing unit tests? [duplicate]
Probably no reason to mock anything here and indeed with your cube() method as it is it is problematic. However you can test the methods of a class in isolation if required by either using a mocking framework such as Mockito to create a partial mock (i.e. mock some methods of a class but call the real code for others)
or simply override the multiply() method in an anonymous class such as below although you would need to change your code in cube to a * multiply(a, a)
@Test
public void testCube(){
compute c = createMock(9);
Assert.assertTrue(27, c.cube(3));
}
public compute createMock(final int result){
compute c = new compute(){
@Override
public int multiply(int a, int b){
return result;
}
};
}
How to test internal function into function in angular?
I think something like this could work.
it('should call popupSuccess on success', () => {
component.onSubmitForm();
// get the 2nd argument
const successCallback = mockMyService.edit.calls.mostRecent().args[1];
successCallback();
expect(mockPopupService.popupSuccess).toHaveBeenCalled();
});
it('should call popupFailure on failure', () => {
component.onSubmitForm();
// get the 3rd argument
const failCallback = mockMyService.edit.calls.mostRecent().args[2];
failCallback();
expect(mockPopupService.popupFailure).toHaveBeenCalled();
});
Should I mock all the dependencies when unit testing?
Correct. You should mock things that depend on anything persistent or external in order to prevent the test from depending on anything persistent or external.
If the dependency does not depend on anything persistent or external, the only benefit you gain from mocking it is that the test will work properly even if the dependency is wrong - but that's assuming the mock works properly. For that you need to either:
Write a mock that emulates the dependency completely.
Write a mock that emulates the dependency for the specific cases that will be used in the test.
The first option is outright ridiculous - why should your mock be any better than the original dependency? After all, it's safe to assume much more effort was invested in the original dependency than in the mock...
The second option means your mock knows the exact details of the implementation - otherwise you won't know how the implementation uses the dependency so you don't know how to mock those specific uses. This means the test does not serve one of the main purposes of unit tests - verifying that the code works properly after changes to the implementation.
The drawbacks of mocking are too big and the advantages are too small - especially considering that you can always run the dependency's tests to check if it works properly...
Unit testing a method that calls another method
This is a classic state-based test vs. behavior-based test scenario.
In this ridiculously simple example testing the output is fine. At some point though, you'll run into tests where inspecting the state after execution is complicated. Instead you want to check the behavior (e.g. verify that changeit was called with a specific value).
At that point you probably should look into a mock object framework like Rhino.Mocks (.Net) or Mockito (Java) and start writing more interface based code.
How to unit test this function without mock asserts?
Problem
I get your concerns. Verifying internal behaviour instead of inputs vs outputs couples your tests to implementation details and makes them brittle when you do refactorings. Fowler coined this testing style mockist testing in his article Mocks aren't Stubs where he explains and compares mockist and classical testing in detail.
Which testing style is more suitable depends on the programming language used, the system architecture and personal preference.
I'm more of a classical testing guy as well, although I sometimes also rely heavily on mocking if it makes for simpler tests.
Solution
That being said, a solution to your problem might be to inverse the control between Process()
and its clients: instead of delegating work to services directly, have it collect the tasks that need to be done and return it. This way you can do regular asserts on the return value of Process
.
In pseudo code:
FUNCTION AssembleProcessingActions (Options) : List OF Action
actions := NEW List OF Action
IF Options.Option1 THEN
actions.Add(Service1.DoSomethingWithItems)
FI
IF Options.Option2 THEN
actions.Add(Service2.DoSomethingWithItems)
FI
IF Options.Option1 OR Options.Option2 THEN
actions.Add(Orchestration2.DoSomething)
FI
RETURN actions
END FUNCTION
Note that I removed the checks to HasAnyItems
. I think they belong inside the DoSomethingWithItems()
methods.
Conclusion
Generally speaking, if your system design is functional rather than object oriented it will lend itself more easily towards classical testing.
This of course does not mean that you cannot have methods on objects anymore and everything should be a static function inside a static utility class. AssembleProcessingActions()
could and should be a method of the type Options
. The point is that it should not change the state of the Options
instance or its dependencies.
Mock functions in Go
Personally, I don't use gomock
(or any mocking framework for that matter; mocking in Go is very easy without it). I would either pass a dependency to the downloader()
function as a parameter, or I would make downloader()
a method on a type, and the type can hold the get_page
dependency:
Method 1: Pass get_page()
as a parameter of downloader()
type PageGetter func(url string) string
func downloader(pageGetterFunc PageGetter) {
// ...
content := pageGetterFunc(BASE_URL)
// ...
}
Main:
func get_page(url string) string { /* ... */ }
func main() {
downloader(get_page)
}
Test:
func mock_get_page(url string) string {
// mock your 'get_page()' function here
}
func TestDownloader(t *testing.T) {
downloader(mock_get_page)
}
Method2: Make download()
a method of a type Downloader
:
If you don't want to pass the dependency as a parameter, you could also make get_page()
a member of a type, and make download()
a method of that type, which can then use get_page
:
type PageGetter func(url string) string
type Downloader struct {
get_page PageGetter
}
func NewDownloader(pg PageGetter) *Downloader {
return &Downloader{get_page: pg}
}
func (d *Downloader) download() {
//...
content := d.get_page(BASE_URL)
//...
}
Main:
func get_page(url string) string { /* ... */ }
func main() {
d := NewDownloader(get_page)
d.download()
}
Test:
func mock_get_page(url string) string {
// mock your 'get_page()' function here
}
func TestDownloader() {
d := NewDownloader(mock_get_page)
d.download()
}
Related Topics
How to Fill an Array With Random Values from a Range
How to Set Multiple Conditions for a Loop
How to Get a Stack Trace for C++ Using Gcc With Line Number Information
Read File Line by Line Using Ifstream in C++
Why Do We Need Virtual Functions in C++
Storing C++ Template Function Definitions in a .Cpp File
How Do Malloc() and Free() Work
Conditions For Automatic Generation of Default/Copy/Move Ctor and Copy/Move Assignment Operator
What Is a "Span" and When Should I Use One
How to Determine Opencv Version
C++ Reading CSV File and Assigning Values to Array
How to Best Silence a Warning About Unused Variables
How to Set, Clear, and Toggle a Single Bit
Why Does an Overridden Function in the Derived Class Hide Other Overloads of the Base Class
Passing Capturing Lambda as Function Pointer