Enhanced Extension Methods

Our team just started unittesting and taunting, and we came across some discussions using extension methods. The question is what is a good approach to testing classes that use extension methods. That is, we have an Enum like this.

public enum State { [LangID(2817)] Draft = 0, [LangID(2832)] Booked = 1, [LangID(1957)] Overdue = 2, [LangID(2834)] Checked = 3, } 

Uses the extension method:

 public static string GetDescription(this Enum _enum) { Type type = _enum.GetType(); MemberInfo[] memInfo = type.GetMember(_enum.ToString()); if (memInfo != null && memInfo.Length > 0) { object[] attrs = memInfo[0].GetCustomAttributes(typeof(LangID), false); if (attrs != null && attrs.Length > 0) return LanguageDB.GetString(((LangID)attrs[0]).ID); } return _enum.ToString(); } 

which will again be called by the tested class, for example.

 public class SUT(){ public void MethodUnderTest(){ string description = SomeObject.Status.GetDescription();//Status is Type State } } 

In this example, the enumeration gets a description in the user's language through LanguageDB, which, unfortunately, is not entered inside the class, since it is static. We could, of course, exaggerate this lot, but this would be a great investment, given that the code works almost flawlessly. Any good suggestion?

+4
source share
3 answers

If you use the MS test suite, you can do very simple refactoring and be able to use Accessors to inject a layout into your object of a static type.

Let's say you have a code like this:

 public static void Save(this Entity data) { Repository.Instance.Save(data); } 

Static in static ... hard to check? Not really. Change the extension class as follows:

 private static Repository Instance { get { return _repository ?? Repository.Instance; } } private static Repository _repository = null; public static void Save(this Entity data) { Instance.Save(data); } 

Simple refactoring. Now you can use the accessory to set your layout during testing ...

 [TestInitialize(), DebuggerStepThrough] public void Setup() { MyEntityExtensions_Accessor._repository = new Mock<IRepository>(); } 
+7
source

almost flawless ?; -)

Rule 1: If it cannot be tested, do not record it.

Rule 2: Many things look as if they will hurt, but do not.

How confident are you that this refactoring will be a great investment?

Rule 0: The rules are intended to guide the Sages and obey the Idiots.

This is a call to judgment, how likely is it that you avoid a defect in this method through work? I assume that in this case the benefits of refactoring this method are pretty small.

+5
source

One idea for testing the extension method itself would be to have a private method that does all the work that gets the LanguageDB injection. A public method will call a private method with a static language, but you would actually test the private method through reflection and pass the layout of the object.

As for testing the actual class being tested, you will probably have to come up with a way to replace the static language LanguageDB - perhaps just exclude it and verify that you are getting the actual enumeration names. In the end, you've already tested that the extension works elsewhere, so you don't need to test it again in this class.

Ultimately, you will find that static objects are difficult to test. The real answer, you guessed it, is to reorganize a better design that does not rely on static objects if they can be avoided (although this seems to be a good candidate). Perhaps you can just refactor the injection.

+1
source

All Articles