4 Appended my answer to handle the white-box unit-test notion, to put the answer in full perspective of what the question asked.
source | link

If you're undertaking Test-Driven Development, then in theory all your unit-testing should be black-box. This is your "test-first approach". You write the contract (interface), write the tests for that contract, and then the contract is fulfilled by the implementation. The test therefore knows nothing, and should know nothing, about the implementation.

After all, when you write a test, what are you testing? Public methods/functions.

If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right? He shouldn't have to throw it away and write his own interface and tests.

Where this falls apart somewhat is when you need to mock something that the implementation depends on, but if you find yourself in the situation whereby you're mocking something that is never exposed publically, then you've made a mistake, and you need to look to Dependency Injection et al. Therefore I would argue that white-box unit-testing, not black, ought to be the exception.

Consider 'Testing on the Toilet - Test Behaviour Not Implementation', wherein a class's implementation is altered but the tests should still be valid.

However, if you need to make sure your code coverage is up (i.e. make sure all the conditional paths are tested within the implementation), then you would absolutely need to white-box unit-test, because the only way you can know what your paths are is by looking at the paths in the implementation.

If you're undertaking Test-Driven Development, then in theory all your unit-testing should be black-box. This is your "test-first approach". You write the contract (interface), write the tests for that contract, and then the contract is fulfilled by the implementation. The test therefore knows nothing, and should know nothing, about the implementation.

After all, when you write a test, what are you testing? Public methods/functions.

If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right? He shouldn't have to throw it away and write his own interface and tests.

Where this falls apart somewhat is when you need to mock something that the implementation depends on, but if you find yourself in the situation whereby you're mocking something that is never exposed publically, then you've made a mistake, and you need to look to Dependency Injection et al. Therefore I would argue that white-box unit-testing, not black, ought to be the exception.

Consider 'Testing on the Toilet - Test Behaviour Not Implementation', wherein a class's implementation is altered but the tests should still be valid.

If you're undertaking Test-Driven Development, then in theory all your unit-testing should be black-box. This is your "test-first approach". You write the contract (interface), write the tests for that contract, and then the contract is fulfilled by the implementation. The test therefore knows nothing, and should know nothing, about the implementation.

After all, when you write a test, what are you testing? Public methods/functions.

If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right? He shouldn't have to throw it away and write his own interface and tests.

Where this falls apart somewhat is when you need to mock something that the implementation depends on, but if you find yourself in the situation whereby you're mocking something that is never exposed publically, then you've made a mistake, and you need to look to Dependency Injection et al. Therefore I would argue that white-box unit-testing, not black, ought to be the exception.

Consider 'Testing on the Toilet - Test Behaviour Not Implementation', wherein a class's implementation is altered but the tests should still be valid.

However, if you need to make sure your code coverage is up (i.e. make sure all the conditional paths are tested within the implementation), then you would absolutely need to white-box unit-test, because the only way you can know what your paths are is by looking at the paths in the implementation.

3 clarified the 'mistake' of mocking a dependency
source | link

If you're undertaking Test-Driven Development, then in theory all your unit-testing should be black-box. This is your "test-first approach". You write the contract (interface), write the tests for that contract, and then the contract is fulfilled by the implementation. The test therefore knows nothing, and should know nothing, about the implementation.

After all, when you write a test, what are you testing? Public methods/functions.

If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right? He shouldn't have to throw it away and write his own interface and tests.

Where this falls apart somewhat is when you need to mock something that the implementation depends on, but if you find yourself in thatthe situation whereby you're mocking something that is never exposed publically, then you've made a mistake, and you need to look to Dependency Injection et al. Therefore I would argue that white-box unit-testing, not black, ought to be the exception.

Consider 'Testing on the Toilet - Test Behaviour Not Implementation', wherein a class's implementation is altered but the tests should still be valid.

If you're undertaking Test-Driven Development, then in theory all your unit-testing should be black-box. This is your "test-first approach". You write the contract (interface), write the tests for that contract, and then the contract is fulfilled by the implementation. The test therefore knows nothing, and should know nothing, about the implementation.

After all, when you write a test, what are you testing? Public methods/functions.

If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right? He shouldn't have to throw it away and write his own interface and tests.

Where this falls apart somewhat is when you need to mock something that the implementation depends on, but if you find yourself in that situation then you've made a mistake, and you need to look to Dependency Injection et al. Therefore I would argue that white-box unit-testing, not black, ought to be the exception.

Consider 'Testing on the Toilet - Test Behaviour Not Implementation', wherein a class's implementation is altered but the tests should still be valid.

If you're undertaking Test-Driven Development, then in theory all your unit-testing should be black-box. This is your "test-first approach". You write the contract (interface), write the tests for that contract, and then the contract is fulfilled by the implementation. The test therefore knows nothing, and should know nothing, about the implementation.

After all, when you write a test, what are you testing? Public methods/functions.

If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right? He shouldn't have to throw it away and write his own interface and tests.

Where this falls apart somewhat is when you need to mock something that the implementation depends on, but if you find yourself in the situation whereby you're mocking something that is never exposed publically, then you've made a mistake, and you need to look to Dependency Injection et al. Therefore I would argue that white-box unit-testing, not black, ought to be the exception.

Consider 'Testing on the Toilet - Test Behaviour Not Implementation', wherein a class's implementation is altered but the tests should still be valid.

2 added 3 characters in body
source | link

If you're undertaking Test-Driven Development, then in theory all your unit-testing should be black-box. This is your "test-first approach". You write the contract (interface), write the tests for that contract, and then the contract is fulfilled by the implementation. The test therefore knows nothing, and should know nothing, about the implementation.

After all, when you write a test, what are you testing? Public methods/functions.

If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right? He shouldn't have to throw it away and write his own interface and tests.

Where this falls apart somewhat is when you need to mock something that the implementation depends on, but if you find yourself in that situation then you've made a mistake, and you need to look to Dependency Injection et al. Therefore I would argue that white-box unit-testing, not black, ought to be the exception.

Consider 'Testing on the Toilet - Test Behaviour Not Implementation''Testing on the Toilet - Test Behaviour Not Implementation', wherein a class's implementation is altered but the tests should still be valid: https://testing.googleblog.com/2013/08/testing-on-toilet-test-behavior-not.html.

If you're undertaking Test-Driven Development, then in theory all your unit-testing should be black-box. This is your "test-first approach". You write the contract (interface), write the tests for that contract, and then the contract is fulfilled by the implementation. The test therefore knows nothing, and should know nothing, about the implementation.

After all, when you write a test, what are you testing? Public methods/functions.

If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right? He shouldn't have to throw it away and write his own interface and tests.

Where this falls apart somewhat is when you need to mock something that the implementation depends on, but if you find yourself in that situation then you've made a mistake, and you need to look to Dependency Injection et al. Therefore I would argue that white-box unit-testing, not black, ought to be the exception.

Consider 'Testing on the Toilet - Test Behaviour Not Implementation', wherein a class's implementation is altered but the tests should still be valid: https://testing.googleblog.com/2013/08/testing-on-toilet-test-behavior-not.html

If you're undertaking Test-Driven Development, then in theory all your unit-testing should be black-box. This is your "test-first approach". You write the contract (interface), write the tests for that contract, and then the contract is fulfilled by the implementation. The test therefore knows nothing, and should know nothing, about the implementation.

After all, when you write a test, what are you testing? Public methods/functions.

If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right? He shouldn't have to throw it away and write his own interface and tests.

Where this falls apart somewhat is when you need to mock something that the implementation depends on, but if you find yourself in that situation then you've made a mistake, and you need to look to Dependency Injection et al. Therefore I would argue that white-box unit-testing, not black, ought to be the exception.

Consider 'Testing on the Toilet - Test Behaviour Not Implementation', wherein a class's implementation is altered but the tests should still be valid.

1
source | link