Skip to main content
Commonmark migration
Source Link
  1. If something requires only a method, there is no need to make it a class just to follow the "do one thing" metapher. "Do one thing" does not mean one should convert every function into a class. If something requires not more than one function, especially a small static function, just keep it as a function.

    If something requires only a method, there is no need to make it a class just to follow the "do one thing" metapher. "Do one thing" does not mean one should convert every function into a class. If something requires not more than one function, especially a small static function, just keep it as a function.

    In case one really needs to inject a function into a class for mocking purposes, one can use std::function (C++ 11) for a constructor parameter to inject a functional object directly, without an extra polymorphic class.

  2. read_file_name_from_cmd_line looks like a standalone static method for which it is probably acceptable to make it public for testing purposes. If you don't like having public methods in FooProject which are not part of the required interface, you can probably move read_file_name_from_cmd_line into a different class, maybe a general helper class for command line parsing.

  3. A constructor call like std::ifstream file(file_name); does not require a test, this is part of the standard lib and should be tested by their authors. However, it might be a good idea to create a "seam" here (like a load method which takes directly an istream) allowing to replace the "real" file stream creation by a "memory stream creation" for testing purposes.

  4. parse_ini_config could be a public member of IniConfig, which would make it simpler to test without any extra helper classes. A component IniConfig can usually be tested without mocking or DI.

  5. So given all the steps in FooProject::load have unit tests, it is debatable whether FooProject::load needs a unit test on its own, or if an integration test (using a real file) would be enough. But even for a unit test, I would suggest to only mock out the "outer world I/O", which means the file access and m_window_system.create_window. There is no need to create a mock for every intermediate step on its own.

  6. If the latter unit test fails for some input, and one cannot see the root cause immediately, then you one debug the test manually once, and identify the step or component which failed. Then should be to add a new unit test to the list of unit tests for that specific component which validates exactly that failure. There is usually no need to have the unit or integration test for FooProject::load showing the specific failing component, that is the responsibility of the tests for the individual components.

In case one really needs to inject a function into a class for mocking purposes, one can use std::function (C++ 11) for a constructor parameter to inject a functional object directly, without an extra polymorphic class.

  1. read_file_name_from_cmd_line looks like a standalone static method for which it is probably acceptable to make it public for testing purposes. If you don't like having public methods in FooProject which are not part of the required interface, you can probably move read_file_name_from_cmd_line into a different class, maybe a general helper class for command line parsing.

  2. A constructor call like std::ifstream file(file_name); does not require a test, this is part of the standard lib and should be tested by their authors. However, it might be a good idea to create a "seam" here (like a load method which takes directly an istream) allowing to replace the "real" file stream creation by a "memory stream creation" for testing purposes.

  3. parse_ini_config could be a public member of IniConfig, which would make it simpler to test without any extra helper classes. A component IniConfig can usually be tested without mocking or DI.

  4. So given all the steps in FooProject::load have unit tests, it is debatable whether FooProject::load needs a unit test on its own, or if an integration test (using a real file) would be enough. But even for a unit test, I would suggest to only mock out the "outer world I/O", which means the file access and m_window_system.create_window. There is no need to create a mock for every intermediate step on its own.

  5. If the latter unit test fails for some input, and one cannot see the root cause immediately, then you one debug the test manually once, and identify the step or component which failed. Then should be to add a new unit test to the list of unit tests for that specific component which validates exactly that failure. There is usually no need to have the unit or integration test for FooProject::load showing the specific failing component, that is the responsibility of the tests for the individual components.

  1. If something requires only a method, there is no need to make it a class just to follow the "do one thing" metapher. "Do one thing" does not mean one should convert every function into a class. If something requires not more than one function, especially a small static function, just keep it as a function.

In case one really needs to inject a function into a class for mocking purposes, one can use std::function (C++ 11) for a constructor parameter to inject a functional object directly, without an extra polymorphic class.

  1. read_file_name_from_cmd_line looks like a standalone static method for which it is probably acceptable to make it public for testing purposes. If you don't like having public methods in FooProject which are not part of the required interface, you can probably move read_file_name_from_cmd_line into a different class, maybe a general helper class for command line parsing.

  2. A constructor call like std::ifstream file(file_name); does not require a test, this is part of the standard lib and should be tested by their authors. However, it might be a good idea to create a "seam" here (like a load method which takes directly an istream) allowing to replace the "real" file stream creation by a "memory stream creation" for testing purposes.

  3. parse_ini_config could be a public member of IniConfig, which would make it simpler to test without any extra helper classes. A component IniConfig can usually be tested without mocking or DI.

  4. So given all the steps in FooProject::load have unit tests, it is debatable whether FooProject::load needs a unit test on its own, or if an integration test (using a real file) would be enough. But even for a unit test, I would suggest to only mock out the "outer world I/O", which means the file access and m_window_system.create_window. There is no need to create a mock for every intermediate step on its own.

  5. If the latter unit test fails for some input, and one cannot see the root cause immediately, then you one debug the test manually once, and identify the step or component which failed. Then should be to add a new unit test to the list of unit tests for that specific component which validates exactly that failure. There is usually no need to have the unit or integration test for FooProject::load showing the specific failing component, that is the responsibility of the tests for the individual components.

  1. If something requires only a method, there is no need to make it a class just to follow the "do one thing" metapher. "Do one thing" does not mean one should convert every function into a class. If something requires not more than one function, especially a small static function, just keep it as a function.

    In case one really needs to inject a function into a class for mocking purposes, one can use std::function (C++ 11) for a constructor parameter to inject a functional object directly, without an extra polymorphic class.

  2. read_file_name_from_cmd_line looks like a standalone static method for which it is probably acceptable to make it public for testing purposes. If you don't like having public methods in FooProject which are not part of the required interface, you can probably move read_file_name_from_cmd_line into a different class, maybe a general helper class for command line parsing.

  3. A constructor call like std::ifstream file(file_name); does not require a test, this is part of the standard lib and should be tested by their authors. However, it might be a good idea to create a "seam" here (like a load method which takes directly an istream) allowing to replace the "real" file stream creation by a "memory stream creation" for testing purposes.

  4. parse_ini_config could be a public member of IniConfig, which would make it simpler to test without any extra helper classes. A component IniConfig can usually be tested without mocking or DI.

  5. So given all the steps in FooProject::load have unit tests, it is debatable whether FooProject::load needs a unit test on its own, or if an integration test (using a real file) would be enough. But even for a unit test, I would suggest to only mock out the "outer world I/O", which means the file access and m_window_system.create_window. There is no need to create a mock for every intermediate step on its own.

  6. If the latter unit test fails for some input, and one cannot see the root cause immediately, then you one debug the test manually once, and identify the step or component which failed. Then should be to add a new unit test to the list of unit tests for that specific component which validates exactly that failure. There is usually no need to have the unit or integration test for FooProject::load showing the specific failing component, that is the responsibility of the tests for the individual components.

added 65 characters in body
Source Link
Doc Brown
  • 220.3k
  • 35
  • 410
  • 623
  1. If something requires only a method, there is no need to make it a class just to follow the "do one thing" metapher. "Do one thing" does not mean one should convert every function into a class. If something requires not more than one function, especially a small static function, just keep it as a function.

In case one really needs to inject a function into a class for mocking purposes, one can use std::function (C++ 11) for a constructor parameter to inject a functional object directly, without an extra polymorphic class.

  1. read_file_name_from_cmd_line looks like a standalone static method for which it is probably acceptable to make it public for testing purposes. If you don't like having public methods in FooProject which are not part of the required interface, you can probably move read_file_name_from_cmd_line into a different class, maybe a general helper class for command line parsing.

  2. A constructor call like std::ifstream file(file_name); does not require a test, this is part of the standard lib and should be tested by their authors. However, it might be a good idea to create a "seam" here (like a load method which takes directly an istream) allowing to replace the "real" file stream creation by a "memory stream creation" for testing purposes.

  3. parse_ini_config could be a public member of IniConfig, which would make it simpler to test without any extra helper classes. A component IniConfig can usually be tested without mocking or DI.

  4. So given all the steps in FooProject::load have unit tests, it is debatable whether FooProject::load needs a unit test on its own, or if an integration test (using a real file) would be enough. But even for a unit test, I would suggest to only mock out the "outer world I/O", which means the file access and m_window_system.create_window. There is no need to create a mock for every intermediate step on its own.

  5. If the latter unit test fails for some input, and youone cannot see the root cause immediately, then you canone debug the test manually once, and identify the step /or component which failed. Then youshould be to add a new unit test to the list of unit tests for that specific component which validates exactly that failure. There is usually no need to to have the unit or integration test for FooProject::load showing the specific failing component, that is the responsibility of the tests for the individual componentcomponents.

  1. If something requires only a method, there is no need to make it a class just to follow the "do one thing" metapher. "Do one thing" does not mean one should convert every function into a class. If something requires not more than one function, especially a small static function, just keep it as a function.

In case one really needs to inject a function into a class for mocking purposes, one can use std::function (C++ 11) for a constructor parameter to inject a functional object directly, without an extra polymorphic class.

  1. read_file_name_from_cmd_line looks like a standalone static method for which it is probably acceptable to make it public for testing purposes. If you don't like having public methods in FooProject which are not part of the required interface, you can probably move read_file_name_from_cmd_line into a different class, maybe a general helper class for command line parsing.

  2. A constructor call like std::ifstream file(file_name); does not require a test, this is part of the standard lib and should be tested by their authors. However, it might be a good idea to create a "seam" here allowing to replace the "real" file stream creation by a "memory stream creation" for testing purposes.

  3. parse_ini_config could be a public member of IniConfig, which would make it simpler to test without any extra helper classes. A component IniConfig can usually be tested without mocking or DI.

  4. So given all the steps in FooProject::load have unit tests, it is debatable whether FooProject::load needs a unit test on its own, or if an integration test (using a real file) would be enough. But even for a unit test, I would suggest to only mock out the "outer world I/O", which means the file access and m_window_system.create_window. There is no need to create a mock for every intermediate step on its own.

  5. If the latter unit test fails for some input, and you cannot see the root cause immediately, then you can debug the test manually once, and identify the step / component which failed. Then you add a new unit test to the list of unit tests for that specific component which validates exactly that failure. There is usually no need to to have the unit or integration test for FooProject::load showing the specific failing component, that is the responsibility of the tests for the individual component.

  1. If something requires only a method, there is no need to make it a class just to follow the "do one thing" metapher. "Do one thing" does not mean one should convert every function into a class. If something requires not more than one function, especially a small static function, just keep it as a function.

In case one really needs to inject a function into a class for mocking purposes, one can use std::function (C++ 11) for a constructor parameter to inject a functional object directly, without an extra polymorphic class.

  1. read_file_name_from_cmd_line looks like a standalone static method for which it is probably acceptable to make it public for testing purposes. If you don't like having public methods in FooProject which are not part of the required interface, you can probably move read_file_name_from_cmd_line into a different class, maybe a general helper class for command line parsing.

  2. A constructor call like std::ifstream file(file_name); does not require a test, this is part of the standard lib and should be tested by their authors. However, it might be a good idea to create a "seam" here (like a load method which takes directly an istream) allowing to replace the "real" file stream creation by a "memory stream creation" for testing purposes.

  3. parse_ini_config could be a public member of IniConfig, which would make it simpler to test without any extra helper classes. A component IniConfig can usually be tested without mocking or DI.

  4. So given all the steps in FooProject::load have unit tests, it is debatable whether FooProject::load needs a unit test on its own, or if an integration test (using a real file) would be enough. But even for a unit test, I would suggest to only mock out the "outer world I/O", which means the file access and m_window_system.create_window. There is no need to create a mock for every intermediate step on its own.

  5. If the latter unit test fails for some input, and one cannot see the root cause immediately, then you one debug the test manually once, and identify the step or component which failed. Then should be to add a new unit test to the list of unit tests for that specific component which validates exactly that failure. There is usually no need to have the unit or integration test for FooProject::load showing the specific failing component, that is the responsibility of the tests for the individual components.

Source Link
Doc Brown
  • 220.3k
  • 35
  • 410
  • 623

  1. If something requires only a method, there is no need to make it a class just to follow the "do one thing" metapher. "Do one thing" does not mean one should convert every function into a class. If something requires not more than one function, especially a small static function, just keep it as a function.

In case one really needs to inject a function into a class for mocking purposes, one can use std::function (C++ 11) for a constructor parameter to inject a functional object directly, without an extra polymorphic class.

  1. read_file_name_from_cmd_line looks like a standalone static method for which it is probably acceptable to make it public for testing purposes. If you don't like having public methods in FooProject which are not part of the required interface, you can probably move read_file_name_from_cmd_line into a different class, maybe a general helper class for command line parsing.

  2. A constructor call like std::ifstream file(file_name); does not require a test, this is part of the standard lib and should be tested by their authors. However, it might be a good idea to create a "seam" here allowing to replace the "real" file stream creation by a "memory stream creation" for testing purposes.

  3. parse_ini_config could be a public member of IniConfig, which would make it simpler to test without any extra helper classes. A component IniConfig can usually be tested without mocking or DI.

  4. So given all the steps in FooProject::load have unit tests, it is debatable whether FooProject::load needs a unit test on its own, or if an integration test (using a real file) would be enough. But even for a unit test, I would suggest to only mock out the "outer world I/O", which means the file access and m_window_system.create_window. There is no need to create a mock for every intermediate step on its own.

  5. If the latter unit test fails for some input, and you cannot see the root cause immediately, then you can debug the test manually once, and identify the step / component which failed. Then you add a new unit test to the list of unit tests for that specific component which validates exactly that failure. There is usually no need to to have the unit or integration test for FooProject::load showing the specific failing component, that is the responsibility of the tests for the individual component.