Reputation: 740
As the title, the code itself as following
internal static class ThumbnailPresentationLogic
{
public static string GetThumbnailUrl(List<Image> images)
{
if (images == null || images.FirstOrDefault() == null)
{
return ImageRetrievalConfiguration.MiniDefaultImageFullUrl;
}
Image latestImage = (from image in images
orderby image.CreatedDate descending
select image).First();
Uri fullUrl;
return
Uri.TryCreate(new Uri(ImageRetrievalConfiguration.GetConfig().ImageRepositoryName), latestImage.FileName,
out fullUrl)
? fullUrl.AbsoluteUri
: ImageRetrievalConfiguration.MiniDefaultImageFullUrl;
}
}
I don't want the unit test go through any methods in ImageRetrievalConfiguration
class, so how can I mock ImageRetrievalConfiguration
and pass it into ThumbnailPresentationLogic
class ??
Upvotes: 0
Views: 2671
Reputation: 2358
I am not sure that is possible through Moq I use Rhino Mocks. What I usually do in this situation is use Spring.NET and provide an alternative mock that I call in tests as apposed to the one in production. This works really well for me especially with areas that use external webservices, datasources or the situation your have raised.
You then Unit Test ImageRetrievalConfiguration seperatly and ensure it works as expected. MockImageRetrievalConfiguration can return results based on how you wish it to react in your testing environment. This will maximize your test converage with the flexibility of mocking.
internal static class SpringApplicationContext
{
private static IApplicationContext applicationContext = null;
static SpringApplicationContext()
{
applicationContext = ContextRegistry.GetContext();
}
public static IApplicationContext ApplicationContext
{
get { return applicationContext; }
}
}
public interface IImageRetrievalData
{
string ImageRepositoryName{get;set;}
}
public interface IImageRetrievalConfiguration
{
IImageRetrievalData GetConfig();
}
public class MockImageRetrievalConfiguration : IImageRetrievalConfiguration
{
public IImageRetrievalData GetConfig()
{
//mock implementation
}
}
public class ImageRetrievalConfiguration : IImageRetrievalConfiguration
{
public IImageRetrievalData GetConfig()
{
//Concrete implementation
}
}
//your code
internal static class ThumbnailPresentationLogic
{
public static string GetThumbnailUrl(List<Image> images)
{
if (images == null || images.FirstOrDefault() == null)
{
return ImageRetrievalConfiguration.MiniDefaultImageFullUrl;
}
Image latestImage = (from image in images orderby image.CreatedDate descending select image).First();
Uri fullUrl;
//Spring
IImageRetrievalConfiguration imageRetrievalConfig = (IImageRetrievalConfiguration) SpringApplicationContext.ApplicationContext["ImageRetrievalConfiguration"];
return Uri.TryCreate(new Uri(imageRetrievalConfig.GetConfig().ImageRepositoryName), latestImage.FileName, out fullUrl) ? fullUrl.AbsoluteUri : ImageRetrievalConfiguration.MiniDefaultImageFullUrl;
}
}
//This would be your testing configuration
<spring>
<context>
<resource uri="config://spring/objects" />
</context>
<objects xmlns="http://www.springframework.net">
<object name="ImageRetrievalConfiguration" type="Tests.MockImageRetrievalConfiguration, Tests" singleton="false" />
</objects>
</spring>
//This would be your production configuration
<spring>
<context>
<resource uri="config://spring/objects" />
</context>
<objects xmlns="http://www.springframework.net">
<object name="ImageRetrievalConfiguration" type="Web.ImageRetrievalConfiguration , Web" singleton="false" />
</objects>
</spring>
You can download the Spring.NET framework from http://www.springframework.net/
Upvotes: 0
Reputation: 174309
You can't do this with Moq, because you would need to intercept the call to the methods of this static class and that is something all "normal" mocking frameworks can't achieve, because they are working purely with type inheritance, automatic code generation and stuff like that.
Intercepting a call to a static method however needs other mechanisms.
Intercepting calls to .NET framework static classes can be done using Moles. I am not sure if it works with your own static classes though.
TypeMock Isolator works with all static classes but it is not free.
However, I really think, you should reconsider your architecture instead.
Upvotes: 2
Reputation: 1500515
How about you split the method into two - one of which takes a "base URI" and "default Url" and one of which doesn't:
internal static class ThumbnailPresentationLogic
{
public static string GetThumbnailUrl(List<Image> images)
{
return GetThumbnailUrl(images,
new Uri(ImageRetrievalConfiguration.GetConfig().ImageRepositoryName),
ImageRetrievalConfiguration.MiniDefaultImageFullUrl);
}
public static string GetThumbnailUrl(List<Image> images, Uri baseUri,
string defaultImageFullUrl)
{
if (images == null || images.FirstOrDefault() == null)
{
return defaultImageFullUrl;
}
Image latestImage = (from image in images
orderby image.CreatedDate descending
select image).First();
Uri fullUrl;
return
Uri.TryCreate(baseUri, latestImage.FileName, out fullUrl)
? fullUrl.AbsoluteUri
: defaultImageFullUrl;
}
}
Then you can test the logic in the "three-parameter" overload, but the public method doesn't really contain any logic. You won't get 100% coverage, but you'll be able to test the real logic involved.
Upvotes: 3