Showing posts with label Unit Test. Show all posts
Showing posts with label Unit Test. Show all posts

Sunday, August 26, 2012

Objective-C: Using Swapping to Mock Method Impelmentaion

Recently I read an interest blog on Unit test in Objective-C. A customized class is defined as method-swizzling helper. With this helper class, two methods in two difference class can be easily swapped at runtime. Therefore, by using this strategy, you can easily mock method calls avoid calling to database or making HTTP requests.

The key points for this helper class is based on Objective-C runtime functions.

class_getClassMethod(...)
method_exchangeImplementations(...)

The first method is used to get a class method as a data type Method. The original and swapped methods can be obtained by this function call. Then the second method is used to make an exchange of method implementation.

The blog has an example of this usage. It looks very easy to make a mock of a method implementation, which is a key practice in unit tests.

Reference


Read More...

Wednesday, November 28, 2007

Rhino.Mocks and AutoMockingContainer

I am working on an ASP.Net project based on WCSF (Web Client Software Factory). For test, I downloaded the latest Rhino.Mocks, NUnit and MbUnit libraries. It works fine at the beginning because all the libraries are new.

For the tests, I need to mock some services and views. I remembered that I used AutoMockingContainer class and I had a generic class for mocking purpose. Then I copied the AutoMockingContainer to the project. After that, my mocking objects stop working and an exception was raised. Here is the error message:

[System.IO.FileLoadException] {"Could not load file
or assembly 'Rhino.Mocks, Version=3.2.0.781, Culture=neutral,
PublicKeyToken=0b3305902db7183f' or one of its dependencies. The located assembly's
manifest definition does not match the assembly reference. (Exception from HRESULT:
0x80131040)":"Rhino.Mocks, Version=3.2.0.781, Culture=neutral, PublicKeyToken=0b3305902db7183f"}
System.IO.FileLoadException


It was very confusing. I thought it might be my Visual Studio or Windows wrong. However, I restarted my Windows and VS again. Still I got the error message. Finally I found that it is the call to AutoMockingContainer class where exception is raised. When I read the error message. I realize that the version of Rhino.Mocks is difference from the same library which is used in the project (ver 3.3.0906).

The problem is that when AutoMockingContainer class is called, CLR is looking for Rhino.Mocks with ver 3.2.0.781. This not-matching caused the exception. It is very interesting. Why does CLR not automatically search for the class or method in a new ver?

Any way, fortunately, I found the source codes of AutoMockingContainer and rebuilt the binary with the same version of Rhino.Mocks. After that, everything works fine. I think that if a library used in a project which depends on old version of assembly, the old version ones have to be installed correctly. It is not as simple as copy library dll files. You have to run deployment or installation to install all the libraries, including dependencies. If both old and new one are used in the same project, the old ones have to be upgraded to new ones.

I think this is an issue of assembly version, and Microsoft has solve the problem. As developers, we have to follow the version management policy to manage version issue. I'll further investigate the issue and try this project with two different versions of Rhino.Mocks library files in one bin directory.

Read More...

Friday, November 09, 2007

Test callback delegate with Rhino.Mocks

Here is the case to test callback delegate by using Rhino.Mocks.

The following service class has a method with a delegate callback as parameter to get a list of products:

// somethere delegate is defined, Product is an another class
public delegate void RetrieveProductListCallback(
bool success, List<product> products);

// service class
public class ProductService
{
// ...
List<product> RetrieveProducts(
RetrieveProductCallbackHander callback)
{ //...
}
}

// Define a method which is used as delegate handler
private void ProductListHandler(bool success,
List<Product> products)
{ // ...
}

RetrieveProductListCallback callback = ProductListHandler;

_productService.RetrieveProducts(callback);


What I want to test this service's callback event. There were no direct information about this issue. I spent several hours googling information on web and tested many different ways. Finally I found a way to test the callback. Here is the summary of the tricks: using Last.Callback and Predicate to do the test. Here are some codes for the test:

[test]
public void ShouldGetAllProudctsFromService()
{
List<Product> products = new List<Product>();
// add some products to the list
bool success = true;
// define a none-null callback
RetrieveProductListCallback callback = delegate {};

using (Mocks.Record())
{
// expect to call method with callback
_productService.
RetrieveProudcts(callback);
// Here is the trick to set up callback
// to be called
LastCall.Callback(
(Predicate<RetrieveProjectListCallback>)
delegate(
RetrieveProductListCallback callbackhander)
{
if (callbackhander != null)
{
callbackhander(success, products);
}
return true;
});

// ...
}

using (Mocks.Playback())
{
// ... assert
}
}
}

Read More...