While Writting Unittests for a Function, Should I Mock the Internal Function Calls Made

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:

  1. Write a mock that emulates the dependency completely.

  2. 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



Leave a reply



Submit