chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
In one of the classes method calls static method Image.FromFile. Here we have the code:

public class MyImage 
{ 
        private Image _image; 
        public string RelPath { get; set; } 
        public bool LoadImage() 
        { 
            bool result = true; 
            try 
            { 
                this._image = Image.FromFile("C:" + this.RelPath); 
            } 
            catch (Exception) 
            { 
                this._image = null; 
                result = false; 
            } 
            return result; 
        } 
} 



I need to write a test, with isolation of Image.FromFile method call, which sets the value of this._image when Image.FromFile called with ecpected parameters to my faked Bitmap object.
It seems to be something like this? but do not work:

        public void LoadImageTest() 
        { 
            MlgImage target = Isolate.Fake.Instance<MlgImage>(Members.CallOriginal); 
            Isolate.WhenCalled(()=>target.RelPath).WillReturn("test"); 
            Image image = new Bitmap(100, 100); 
            FieldInfo fieldInfo = typeof(MlgImage).GetField("_image", BindingFlags.Instance | BindingFlags.NonPublic); 
            var mock = MockManager.MockObject(typeof(Image)) 
            Isolate.WhenCalled((string s) => Image.FromFile(s)).AndArgumentsMatch(s=>s.EndsWith("test")).WillReturn(image); 
            Isolate.Invoke.Method(target, "LoadImage"); 
            Assert.ReferenceEquals(image, fieldInfo.GetValue(target)); 
        } 




Can someone give a suggestion?
asked by atikhomirov (1.6k points)

1 Answer

0 votes
If I understand correctly, you want to make sure the _image field has been loaded properly with your test image.

I would do it like this:
[Test]
[Isolated]
public void LoadImage_PopulatesImageField()
{
   var testImage = new Bitmap(1,1);
   Isolate.WhenCalled(Image.FromFile(null)).WillReturn(testImage);

   var target = new MyImage();
   var targetState = new ObjectState(target);

   target.LoadImage();

   Assert.ReferenceEquals(testImage, targetState.GetField("_image");
}


Things to note:
:arrow: There's no need to create the object under test as a fake - you can just call its c'tor. If you need to fake one of its methods, just pass the real instance into WhenCalled().
:arrow: I faked out any call to Image.FromFile(). You went a more complex route, and conditionally faked it depending on the value of RelPath which you had to fake as well as a result - this seems a bit complex, and I think can be avoided entirely. Unless other calls to Image.FromFile() are supposed to happen, my version would work.
:arrow: There's no need to use the Invoke API to call the method under test as it's public. I just call the method directly. The Invoke APIs are for non-public methods and events.
:arrow: The use of MockManager.Mock() is redundant. Actually, we discourage mixing APIs - Isolate is the entry point for the AAA API, and MockManager is the entry point for the older Reflective API. I strongly recommend using the AAA API as it lends to more readable tests.
:arrow: Note the use of ObjectState - it's a helper class that simplifies the reflection you did around _image. Both would work, but that is simpler.

Please let me know if the test now works as you expect.

Doron
Typemock Support
answered by doron (17.2k points)
...