I am new to rhino mocks and unit testing in general. I am starting to write some tests for my wpf mvvm app. Here is a sample scenario I am trying to test:
The view model:
List<DataItems> _theData = new List<DataItems>();
public MyViewModel(IServer server)
{
_server = server;
InitializeData();
}
private void InitializeData()
{
_server.GetData(MyCallback);
}
private void MyCallback()
{
_theData = _server.TheData;
}
public List<DataItems> VMData
{
get
{
return _theData;
}
}
Server:
public List<DataItems> TheData
{
get
{
return _cachedData;
}
}
public void GetData(Action callBack)
{
//Populate cached data
...
if(callBack != null)
{
callBack();
}
}
In my test, I want to verify that viewModel.VMData.Count == server.TheData.Count. I tried using rhino mocks to stub the server, pre-poulating TheData with some values. The I called the view model constructor, and then tried to compare the counts.
My problem is that I do not know how to get my server to actually call back into my view model. After the vm constructor is called, InitializeData() is called as expected but the stub server's GetData call is not made.
How can I make this simple test work?
if you are stubbing IServer and expecting that the calling a method on the stub will invoke the implementation in your concrete class, that is your misconception. the GetData method on the stub instance will only return what you tell it to, and not execute any code in the concrete dependency. remember that the only thing your stub IServer object has in common with your concrete implemetation of IServer is that they both implement IServer. expecting that the side effects in the method in your concrete implemenation will happen when calling the method on the stub is just faulty.
as to how to make it work: there's not really a good way to do this test as you are stating with the design of these classes as is. you are trying to test that a side effect occurred in the dependency that you are stubbing out of participation. to really test what you want here and if you want to keep these classes with this relationship, i'd suggest that you don't mock server at all and use the real object. redesign the server so that it depends on another component that loads from the cache so you can stub that thing instead.
Related
I'm going to do some unit tests and I am struggling with a MessageBox. I have a MessageBox that is showing a text and an "Ok" button in my code. When I trying to unit test the method that contains the MessageBox.Show("Text"), it pops up in the unit test, too, and I have to click "Ok" before it can pass through, which is a bad.
Does anyone know how to go around it? I think I need some kind of code that fakes this MessageBox and clicking "Ok", but I dont know how to do this. I'm a junior programmer, so please explain it as easy as you can ;) and gladly with some code examples.
This is my code for the MessageBox:
public void GetPopUpWithErrorMessage()
{
MessageBox.Show("Error Message", "text",
MessageBoxButton.OK);
}
Edit
I just realised that Fluent Assertions is used in the project. Does anyone know how to implement that in the test code? is it the same way as #thatguy showed?
You have to create a service that implements an interface that you can mock in your tests.
public interface IMessageBoxService
{
void ShowMessageBox(string title, string message);
}
public class MessageBoxService : IMessageBoxService
{
public void ShowMessageBox(string title, string message)
{
MessageBox.Show(message, title, MessageBoxButton.OK);
}
}
In the class where you use it, you would pass this service by its interface, e.g. in the constructor, so the class only knows its contract, but not its implementation.
public class MyClass
{
private IMessageBoxService _messageBoxService;
public MyClass(IMessageBoxService messageBoxService)
{
_messageBoxService = messageBoxService;
}
public void GetPopUpWithErrorMessage()
{
_messageBoxService.ShowMessageBox("text", "Error Message");
}
}
In the test class, you need to use a mocking framework like Moq that creates a mock object from an interface, which is just a stub that you can use to inject the behavior for any method or property that you use in your test.
In this example using NUnit and Moq, messageBoxService is created as a mock object that implements the IMessageBoxService interface. All methods do nothing unless you specify what they should do or return via Setup, but that is another topic. The last line shows how you could check if a sepcific method on the mock was invoked during the test.
[TestFixture]
public class MyClassTest
{
[Test]
public void MyTest()
{
var messageBoxService = Mock.Of<IMessageBoxService>();
var myClass = new MyClass(messageBoxService);
// ...your test code.
// Checks if the "ShowMessageBox" method in the service was called with any strings
Mock.Get(messageBoxService).Verify(mock => mock.ShowMessageBox(It.IsAny<string>(), It.IsAny<string>()));
}
}
Creating a service and an interface is not just useful for mocking, but also for separating view and logic, as you can extract the calling of a message box to a service which has an implementation hidden behind an interface. Moreover you can easily implement dependency injection via constructors.
I am fairly new to writing mock classes.I am trying to write a test class for the below method and I am not able to proceed with mocking the method call "getSsnValue".
public void setFieldValue(String fieldValue) {
final Field<String> SSN = getSsnField(fieldValue);
if (SSN !=null) {
getSsnValue(SSN ,fieldValue);
}
}
Below is the test written for mocking the method "getSsnField" and is working fine.Can anyone help in understanding how to mock the void method "getSsnValue" so that this method will not be executed during the call "controller.setFieldValue(name);"
Code Snippet:
controller = EasyMock.createMockBuilder(Controller.class).addMockedMethod("getSsnField",String.class).createMock();
EasyMock.expect(controller.getSsnField((String)EasyMock.anyObject())).andReturn(SSN).anyTimes();
EasyMock.replay(controller);
controller.setFieldValue(name);
Are you mocking those methods because they do some heavy-lifting that you can't afford to do in your test? The reason I ask is because, IMO, if you have to create a partial mock like this in order to mock out calls to methods that live in the same class then you are probably testing at a too fine-grained level. In other words, do you really need to mock out those methods?
I also assume that, if you do want to mock those internal methods out then the only reason for the test must be to ensure that if getSsnField(fieldValue) returns a Field, that getSsnValue() is invoked with the same fieldValue.
If you want to continue down that path, here's what you need to do. In EasyMock, to mock out a void method, you don't use expect(...); Instead you just call the method directly on your mock object (before calling replay()). Doing so instructs EasyMock to create the expectation that that void method will be called.
Controller controller = EasyMock.createMockBuilder(Controller.class)
.addMockedMethod("getSsnField", String.class)//
.addMockedMethod("getSsnValue")//
.createMock();
Field<String> SSN = new Field<String>();
String name = "name";
EasyMock.expect(controller.getSsnField(name)).andReturn(SSN).anyTimes();
// Just calling the getSsnValue method on the mock sets up the expectation
// that it must be called
controller.getSsnValue(SSN, name); // Mocking void method here
EasyMock.replay(controller);
controller.setFieldValue(name);
// This step is needed in order to enforce that all mocked methods were
// actually called.
EasyMock.verify(controller);
I have a typical Silverlight application with a WCF service and I am using slsvcutil.exe to generate the standard client proxy to communicate with the web service. I am trying to write unit tests and I'm attempting to use the Silverlight Unit Testing framework and Moq to mock the proxy and remove the service dependency for testing.
I am very new to Moq and having a lot of trouble automatically raising the various Completed events on the mocked proxy automatically when service calls are made to simulate the async calls.
In order to make the proxy "mockable" I've created my own simple interface for the generated proxy calls and their completed events:
public interface IServiceProxy
{
void TestAsync(TestRequest request);
void TestAsync(TestRequest request, object userState);
event EventHandler<TestCompletedEventArgs> TestCompleted;
}
I also subclassed the generated proxy object to implement that interface:
public class MyServiceProxy : GeneratedServiceClient, IServiceProxy, ICommunicationObject
{
// ... overloaded proxy constructors
}
After looking at the Moq documentation, this is how I am attempting to set up the mock to expect the TestAsync() call and immediately raise the TestCompleted event with the result in the EventArgs:
[TestMethod]
public void Test_Returns_Expected()
{
var mockProxy = new Mock<IServiceProxy>();
var result = new TestResponse() { Value = true };
this.mockProxy.Setup(
p => p.TestAsync(It.IsAny<TestRequest>()))
.Raises(p => p.TestCompleted += null, new TestCompletedEventArgs(new object[] { result }, null, false, null));
// rest of the test to actually use the mock and assert things
}
Everything builds fine, but when I attempt to run any kind of test using the mock and set break points the TestCompleted event is never being raised when I call TestAsync().
Is there anything obvious that I am missing or any better ideas about mocking these types of async service proxies in Silverlight?
Thanks!
EDIT:
To be more clear what I am actually trying to test is a helper class I made which takes an instance of IServiceProxy and provides a cleaner service interface for my ViewModel to use by accepting Action<TResponse, Exception> callback parameters rather than dealing with callback events in my ViewModel. I understand how I could mock this as well to directly test my ViewModel but I figured it would be nice to test the helper class by itself first.
Here is an example of what I am talking about:
public class HelperClient : IServiceHelper
{
private IServiceProxy proxy;
public HelperClient(IServiceProxy proxy)
{
this.proxy = proxy;
// register to handle all async callback events
this.proxy.TestCompleted += new EventHandler<TestCompletedEventArgs>(TestCompleted);
}
public void Test(TestRequest request, Action<TestResponse, Exception> response)
{
this.proxy.TestAsync(request, response);
}
private void TestCompleted(object sender, TestCompletedEventArgs e)
{
var response = e.UserState as Action<TestResponse, Exception>;
if (response != null)
{
var ex = GetServiceException(e);
if (ex == null)
{
response(e.Result, null);
}
else
{
response(null, ex);
}
}
}
}
So in my test what I am really doing is mocking ISerivceProxy and passing it in and just attempting to test a service call to make sure the wrapper it invoking the Action correctly:
[TestMethod]
[Asynchronous]
public void Test_Returns_Expected()
{
var mockProxy = new Mock<IServiceProxy>();
var helper = new HelperClient(mockProxy.Object);
bool expectedResult = true;
var result = new TestResponse() { Value = expectedResult };
this.mockProxy.Setup(
p => p.TestAsync(It.IsAny<TestRequest>()))
.Raises(p => p.TestCompleted += null, new TestCompletedEventArgs(new object[] { result }, null, false, null));
helper.Test(new TestRequest(), (response, ex) =>
{
Assert.AreEqual(expectedResult, response.Value);
EnqueueTestComplete();
});
}
The problem is that the mocked proxy object is never raising the TestCompleted event so my response action is never getting invoked to finish the test (even though the test appears to complete successfully the Assert is never actually run). Sorry for such a long post, just trying to show you as much code as possible.
EDIT 2
Added [Asynchronous] and call to EnqueueTestComplete() which I realized I may need to make the test wait for the event to be raised. This did not really help, the event is still never raised so the test just hangs and never completes.
EDIT 3
Aliostad's answer was correct that my setup expectation's signature did not match the actual Test() signature allowing me to pass in a response Action as the second param. Stupid mistake, but that is what was preventing Moq from raising the Completed event. I was also forgetting to pass the Action in as the userState object in the TestCompletedEventArgs so that it would actually be invoked when the Completed event was raised. Also, the [Asynchronous] and EnqueueTestCompleted did not seem to be necessary in this case.
Here is updated test code for anyone interested:
[TestMethod]
public void Test_Returns_Expected()
{
var mockProxy = new Mock<IServiceProxy>();
var helper = new HelperClient(mockProxy.Object);
bool expectedResult = true;
var result = new TestResponse() { Value = expectedResult };
Action<TestResponse, Exception> responseAction = (response, ex) =>
{
Assert.AreEqual(expectedResult, response.Value);
};
this.mockProxy.Setup(
p => p.TestAsync(It.IsAny<TestRequest>(), It.IsAny<Action<TestResponse, Exception>>()))
.Raises(p => p.TestCompleted += null, new TestCompletedEventArgs(new object[] { result }, null, false, responseAction));
helper.Test(new TestRequest(), responseAction);
}
Mocking events is quite a pain and unit tests become brittle. But as you said there is no way around it. But normally you would make the call you are trying to test and block the current thread (using Sleep or other methods) until event is raised (or a time-out).
It is actually not clear what you are testing. I can see a mock and a response, where is the actual real object?
I will update my answer accordingly.
UPDATE
I can see a problem here:
helper.Test(new TestRequest(), (response, ex) =>
{
Assert.AreEqual(expectedResult, response.Value);
EnqueueTestComplete();
});
in the last statement, you are putting EnqueueTestComplete(); and you assert but this action will never be used because it is passed to the moq object.
Also you are setting the expectation for TestAsync(It.IsAny<TestRequest>())) (one argument) while you are calling it with two arguments in the HelperClient (this.proxy.TestAsync(request, response);) and that is why it never gets fired since expectation is not met.
just searched for mock asynchronous WCF client and found this question.
to prevent this situation Moq can .Verify() that p.TestAsync() has been invoked.
//will throw MockException if p.TestAsync() has never been called.
this.mockProxy.Verify(p => p.TestAsync(It.IsAny<TestRequest>()), Times.Once());
I'm in the middle of a Silverlight application and I have a function which needs to call a webservice and using the result complete the rest of the function.
My issue is that I would have normally done a synchronous web service call got the result and using that carried on with the function. As Silverlight doesn't support synchronous web service calls without additional custom classes to mimic it, I figure it would be best to go with the flow of async rather than fight it. So my question relates around whats the best design pattern for working with async calls in program flow.
In the following example I want to use the myFunction TypeId parameter depending on the return value of the web service call. But I don't want to call the web service until this function is called. How can I alter my code design to allow for the async call?
string _myPath;
bool myFunction(Guid TypeId)
{
WS_WebService1.WS_WebService1SoapClient proxy = new WS_WebService1.WS_WebService1SoapClient();
proxy.GetPathByTypeIdCompleted += new System.EventHandler<WS_WebService1.GetPathByTypeIdCompleted>(proxy_GetPathByTypeIdCompleted);
proxy.GetPathByTypeIdAsync(TypeId);
// Get return value
if (myPath == "\\Server1")
{
//Use the TypeId parameter in here
}
}
void proxy_GetPathByTypeIdCompleted(object sender, WS_WebService1.GetPathByTypeIdCompletedEventArgs e)
{
string server = e.Result.Server;
myPath = '\\' + server;
}
Thanks in advance,
Mike
The best would be to use Reactive Extensions. Then (assuming you'd create an extension method IObservable<string> GetPathByTypeId(string typeId) on WS_WebService1SoapClient you can do this:
proxy
.GetPathByTypeId(TypeId)
.Subscribe(server =>
{
//Here you can do stuff with the returned value
});
As close to having synchronous call as it gets :)
Given the asynch nature of Silverlight you cannot return values from myFunction. Instead you can pass an Action which is executed once the service call is complete. See the example code below. I am not sure if it is considered best practice, but I use this "pattern" a lot and it has always worked fine for me.
EDIT
Updated the code below to include multiple arguments in the callback action.
void DoSomething(Guid TypeId, Action<int, bool> Callback)
{
WS_WebService1.WS_WebService1SoapClient proxy = new WS_WebService1.WS_WebService1SoapClient();
proxy.GetPathByTypeIdCompleted += (s, e) =>
{
string server = e.Result.Server;
myPath = '\\' + server;
//
if (myPath == "\\Server1")
{
Callback(888, true);
}
else
{
Callback(999, false);
}
};
proxy.GetPathByTypeIdAsync(TypeId);
}
void CallDoSomething()
{
DoSomething(Guid.NewGuid(), (returnValue1, returnValue2) =>
{
//Here you can do stuff with the returned value(s)
});
}
Put the processing of the GetPathByTypeId result into the GetPathByTypeIdCompleted callback. Assign mypath there. Make mypath a property and implement the INotifyPropertyChanged interface to notify dependents of Mypath that Mypath has changed.
Observer depends on mypath
Observer sets a notification event for mypath
Get Mypath by asynchronous invocation of GetPathByTypeId
Mypath is set, invokes notifiaction of Observer
Observer works with Mypath
I'm looking for some basic examples of using NMock2 to mock database calls for a CRUD application.
Thanks,
Chris
Setup:
[SetUp]
public void SetUp()
{
mocks = new Mockery();
mockDBLayer = _mocks.NewMock<IDBLayer>();
//Inject the dependency somehow
sut = new SUT(_mockDBLayer );
}
Test:
[Test]
public void testMethodName_TestCase()
{
var dbRetrunValue = //whatever type
Expect.Once.On(mockDBLayer).Method("dbMethod").Will(Return.Value(dbRetrunValue));
//exercise
var actual = sut.methodName();
//Assert
...
}
Verification if you want it
[TearDown]
public void TearDown()
{
mocks.VerifyAllExpectationsHaveBeenMet();
}
I like Moq better however:
http://code.google.com/p/moq/
"database calls" is a rough term to guess at - do you mean testing your DAL, or testing a layer above that?
If you mean testing your DAL, you need to look at how you're getting the actual DataReader or DataTable, or whatever, so that you can replace it with the mock.
See blog posts like this that covers IoC and mocking data access , or posts like this that cover mocking a datareader for getting started.