C# Unit Test Getting Started with Complete Code

This article is a supplement of the basic introduction of C# Unit Test from MSDN. As you may find, although technically correct, the MSDN article is confusing here and there, probably because it was written by several people with different assumptions. Another defect of the MSDN article is that the code samples are either too much – so it cannot focus on the point, or too little – so it loses its connection with other essential parts of a complete Unit Test solution. That’s why I am writing this article, with complete code sample tested in VS2013 that you can download.

There are three Sections of this article, with three corresponding VS solutions in the code sample: Basic Unit Test, Unit Test with Stub, and Unit Test with Shim. You should follow the order if you are new to this topic.

Basic Unit Test

Please read the MSDN Unit Test Basics article first, EXCEPT the “Additional tools” section. And refer the “UnitTest” sample in my code.

Note that there are only two projects in the VS solution: Accounts project with only one code class CheckingAccount.cs, and AccountsTest project with only one test class CheckingAccountTest.cs. The mention of BankDB and BankDBTest projects, as well as other interfaces or classes in the MSDN article should all be ignored for now.

Now it should be easy to get the point of Unit Test.

Unit Test with Stub

Now go back to read the “Additional tools” section of the MSDN Unit Test Basics article, esp. the last part “Isolating unit test methods with Microsoft Fakes”. Does it make much sense? I would not be suprised if you think it doesn’t. In fact, there are even errors in the code samples in this part: “var stubBankDb = new MyBank.Stubs.StubIBankDb();” is from an older version of Microsoft Fakes (called Microsoft Moles, just in case you are wondering). In VS2013 it should be “var stubBankDb = new MyBank.Fakes.StubIBankDb();”. Now you understand what I was talking about at the beginning of this article.

OK. Now go ahead and read the MSDN Microsoft Fakes article. This one should make much more sense. And refer to the “UnitTestWithStub” sample in my code.

The addition of a new project BankDB represents a different component that introduces other dependencies, like network connection, database connection, certian files that should be available in the client’s computer on runtime, etc. This is where Stubs are supposed to work. Note that the code samples in the MSDN Fakes article are no longer the Bank/Account ones, while I am still keeping the same context in my code sample.

If you try to follow the article by clicking “Add Fakes Assembly”, you will find the following error message. Deleting the reference is not enough, you may need to delete the Fakes\BankDb.fakes file as well.

7-16-2015 3-12-39 PM

Unit Test with Shim 

The Shim sample code should be pretty straight forward. It’s basically highjacking a call to an external reference and return a preset value.

One problem is that VS2013 Shim generation with System reference seems to be not working well with .net Framework 4.5(.x), with a strange error regarding System.Security.Cryptography. Changing the target framework to 4.6 would work. Or, try VS2015.

sqlite3.def for 3.8.6

EXPORTS
sqlite3_aggregate_context
sqlite3_aggregate_count
sqlite3_auto_extension
sqlite3_backup_finish
sqlite3_backup_init
sqlite3_backup_pagecount
sqlite3_backup_remaining
sqlite3_backup_step
sqlite3_bind_blob

sqlite3_bind_double
sqlite3_bind_int
sqlite3_bind_int64
sqlite3_bind_null
sqlite3_bind_parameter_count
sqlite3_bind_parameter_index
sqlite3_bind_parameter_name
sqlite3_bind_text
sqlite3_bind_text16

sqlite3_bind_value
sqlite3_bind_zeroblob
sqlite3_blob_bytes
sqlite3_blob_close
sqlite3_blob_open
sqlite3_blob_read
sqlite3_blob_reopen
sqlite3_blob_write
sqlite3_busy_handler
sqlite3_busy_timeout
sqlite3_cancel_auto_extension
sqlite3_changes
sqlite3_clear_bindings
sqlite3_close
sqlite3_close_v2
sqlite3_collation_needed
sqlite3_collation_needed16
sqlite3_column_blob
sqlite3_column_bytes
sqlite3_column_bytes16
sqlite3_column_count
sqlite3_column_decltype
sqlite3_column_decltype16
sqlite3_column_double
sqlite3_column_int
sqlite3_column_int64
sqlite3_column_name
sqlite3_column_name16
sqlite3_column_text
sqlite3_column_text16
sqlite3_column_type
sqlite3_column_value
sqlite3_commit_hook
sqlite3_compileoption_get
sqlite3_compileoption_used
sqlite3_complete
sqlite3_complete16
sqlite3_config
sqlite3_context_db_handle
sqlite3_create_collation
sqlite3_create_collation16
sqlite3_create_collation_v2
sqlite3_create_function
sqlite3_create_function16
sqlite3_create_function_v2
sqlite3_create_module
sqlite3_create_module_v2
sqlite3_data_count
sqlite3_db_config
sqlite3_db_filename
sqlite3_db_handle
sqlite3_db_mutex
sqlite3_db_readonly
sqlite3_db_release_memory
sqlite3_db_status
sqlite3_declare_vtab
sqlite3_enable_load_extension
sqlite3_enable_shared_cache
sqlite3_errcode
sqlite3_errmsg
sqlite3_errmsg16
sqlite3_errstr
sqlite3_exec
sqlite3_expired
sqlite3_extended_errcode
sqlite3_extended_result_codes
sqlite3_file_control
sqlite3_finalize
sqlite3_free
sqlite3_free_table
sqlite3_get_autocommit
sqlite3_get_auxdata
sqlite3_get_table
sqlite3_global_recover
sqlite3_initialize
sqlite3_interrupt
sqlite3_last_insert_rowid
sqlite3_libversion
sqlite3_libversion_number
sqlite3_limit
sqlite3_load_extension
sqlite3_log
sqlite3_malloc

sqlite3_memory_alarm
sqlite3_memory_highwater
sqlite3_memory_used
sqlite3_mprintf

sqlite3_mutex_alloc
sqlite3_mutex_enter
sqlite3_mutex_free
sqlite3_mutex_leave
sqlite3_mutex_try
sqlite3_next_stmt
sqlite3_open
sqlite3_open16
sqlite3_open_v2
sqlite3_os_end
sqlite3_os_init
sqlite3_overload_function
sqlite3_prepare
sqlite3_prepare16
sqlite3_prepare16_v2
sqlite3_prepare_v2
sqlite3_profile
sqlite3_progress_handler
sqlite3_randomness
sqlite3_realloc

sqlite3_release_memory
sqlite3_reset
sqlite3_reset_auto_extension
sqlite3_result_blob

sqlite3_result_double
sqlite3_result_error
sqlite3_result_error16
sqlite3_result_error_code
sqlite3_result_error_nomem
sqlite3_result_error_toobig
sqlite3_result_int
sqlite3_result_int64
sqlite3_result_null
sqlite3_result_text
sqlite3_result_text16
sqlite3_result_text16be
sqlite3_result_text16le

sqlite3_result_value
sqlite3_result_zeroblob
sqlite3_rollback_hook
sqlite3_set_authorizer
sqlite3_set_auxdata
sqlite3_shutdown
sqlite3_sleep
sqlite3_snprintf
sqlite3_soft_heap_limit
sqlite3_soft_heap_limit64
sqlite3_sourceid
sqlite3_sql
sqlite3_status

sqlite3_step
sqlite3_stmt_busy
sqlite3_stmt_readonly
sqlite3_stmt_status
sqlite3_strglob
sqlite3_stricmp
sqlite3_strnicmp

sqlite3_test_control
sqlite3_thread_cleanup
sqlite3_threadsafe
sqlite3_total_changes
sqlite3_trace
sqlite3_transfer_bindings
sqlite3_update_hook
sqlite3_uri_boolean
sqlite3_uri_int64
sqlite3_uri_parameter
sqlite3_user_data
sqlite3_value_blob
sqlite3_value_bytes
sqlite3_value_bytes16
sqlite3_value_double
sqlite3_value_int
sqlite3_value_int64
sqlite3_value_numeric_type
sqlite3_value_text
sqlite3_value_text16
sqlite3_value_text16be
sqlite3_value_text16le
sqlite3_value_type
sqlite3_vfs_find
sqlite3_vfs_register
sqlite3_vfs_unregister
sqlite3_vmprintf
sqlite3_vsnprintf
sqlite3_vtab_config
sqlite3_vtab_on_conflict
sqlite3_wal_autocheckpoint
sqlite3_wal_checkpoint
sqlite3_wal_checkpoint_v2
sqlite3_wal_hook
sqlite3_win32_is_nt
sqlite3_win32_mbcs_to_utf8
sqlite3_win32_set_directory
sqlite3_win32_sleep
sqlite3_win32_utf8_to_mbcs
sqlite3_win32_write_debug