Regarding how to use Moq framework for a special case as explained.

135 views
Skip to first unread message

vibhu

unread,
May 30, 2012, 8:42:18 AM5/30/12
to Moq Discussions
Hi All,

I have a question. Please help if You can.

I have a class ABC as shown:

public class ABC
{
public int a { get; set; }
public int b { get; set; }
}

I have a method returning void and just changing the state of the
object it accepts as a input parameter. The Class and method is as
shown:

public class MyClass
{
public void changeObjectState(ABC abc)
{
abc.b = 1;
}
}

Also I have another Class (having a method which calls the above
method). As shown:

public class CallingClass
{
public void callingMethod(int x)
{
ABC abc = new ABC()
{
a = x
};

MyClass obj = new MyClass();
obj.changeObjectState(abc);
}
}


Now I want to write the unit tests and test the method
"callingMethod". Please help on how can I test the same. Also, how can
I use Moq to do the same. I understand the basics of how to use Moq
for unit tests. But I am facing problem in How to Moq the method
"changeObjectState" and how to change the object state within it as it
returns void so I cannot use .Returns()

Thanks in advance.
Vaibhav

Tim Kellogg

unread,
May 30, 2012, 3:16:24 PM5/30/12
to moq...@googlegroups.com

The short answer is that you can't. This would require the ability to mock the new operator. typemock is an expensive alternative to moq that let's you mock things like the new operator. Really you need to restructure your code to avoid creational patterns. Chad Meyers wrote a great explanation on his blog

http://lostechies.com/chadmyers/2010/02/13/composition-versus-inheritance/

--Tim

Sunny

unread,
May 31, 2012, 4:00:52 PM5/31/12
to moq...@googlegroups.com
That is considered bad design.

Why?

1. unit tests should tests single units
2. your implementation is tightly coupled
3. you already has a code to test, it's much better if you first has
the tests, then the code will be easy :)

So, here are your tests, modify your code to pass them:

public void TestMyClassChangeObjectState()
{
//arrange
var abc = new ABC{a = 1};
IMyClass myClass = new MyClass();

//act
myClass.changeObjectState(abc);

//assert
Assert.That(abc.a == 2); //assuming that the method is abc.a++,
put something lese based on the functionality you need
}

public void TestMyClassCreator
{
//arrange
IMyClassCreator creator = new MyClassCreator();

//act
IMyClass myClass = creator.CreateMyClass();

//assert
Assert.That(myClass != null);
}

public void TestCallingClassCallingMethod()
{
//arrange
var myClass = new Mock<IMyClass>();
var myClassCreator = new Mock<IMyClassCreator>();
myClassCreator.Setup(c=>c.CreateMyClass()).Returns(myClass.Object);

var callingClass = new CallingClass(myClassCreator.Object);

//act
callingClass.callingMethod(5);

//assert
myClass.Verify(m=>m.changeObjectState(It.Is<ABC>(d=>d.a == 5), Times.Once());
--
Svetoslav Milenov (Sunny)

Artificial Intelligence is no match for natural stupidity.
Message has been deleted
Message has been deleted

vibhu

unread,
Sep 12, 2012, 5:46:12 AM9/12/12
to moq...@googlegroups.com
Thanks a lot All of you for your concern!!!!.
 
:)

Zelalem

unread,
Apr 11, 2013, 11:46:01 PM4/11/13
to moq...@googlegroups.com



On Fri, Jun 8, 2012 at 10:14 AM, Zelalem <zde...@gmail.com> wrote:
Hello Vabhu,

How about if you restructure the code a bit. There seems to be a tight coupling. CallingClass is tightly coupled with ABC and MyClass.
You can use either constructor/property injection.

How about if you restructure CallingClass as.

public class CallingClass
   {
         private ABC _abc;
         private MyClass _obj;
      
      public CallingClass(ABC abc, MyClass obj)
       {
           //depending on your requirement, you might throw if null comes in for either of them. But, that all will depend on your requirement.
           _abc=abc;
           _obj = obj;
       }

       public void callingMethod(int x)
       {         
            // you might check for null here especially if your constructor allows null to be set to _abc and _obj. But, still - this shouldn't affect your testability.
           _abc.a =x;
            _obj.changeObjectState(abc);
       }
   }


As you can see, no logic changed at all. Just a little restructure of the code. But, this time, it's much easier for you to create a mocked instance of ABC and MyClass and use those to test CallingClass. Just inject those mocked instances to CallingClass's constructor and you will have an instance to do your tests against.
This way, your class (CallingClass) is NOT tide up with only one implementation.

Let me know if this helps,

Thanks,
Bsharper



Zelalem

unread,
Apr 11, 2013, 11:56:33 PM4/11/13
to moq...@googlegroups.com
Hello Vibhu,
Thanks,
Zelalem!


On Wed, May 30, 2012 at 5:42 AM, vibhu <vaibhav...@gmail.com> wrote:
Reply all
Reply to author
Forward
0 new messages