I am using MVVM pattern and silverlight 4.0 and Moq for testing.
In the view model constructor, am passing an IEventAggregator object. This object is used to subscribe to an event called SelectionChangedEvent.
In the test method I am doing like this:
this.selectedEvent = new Mock<SelectionChangedEvent>();
this.eventAggregator.Setup(x => x.GetEvent<SelectionChangedEvent>()).Returns(this.selectedEvent.Object);
var viewModel = new ViewModel(this.eventAggregator);
I want to test that the event is getting subscribed when the constructor is called.
How can I verify this?
[Disclaimer: I haven't been able to test this under Silverlight]
Here's a possible solution that basically executes a callback to set an external boolean when Subscribe is called on the event. See comments below though.
[Test]
public void Constructor_CallsSubscribeOnSelectionChangeEvent()
{
var subscribeCalled = false;
var selectedEvent = new Mock<SelectionChangedEvent>();
var eventAggregator = new Mock<IEventAggregator>();
selectedEvent
.Setup(x => x.Subscribe(
It.IsAny<Action<object>>(),
It.IsAny<ThreadOption>(),
It.IsAny<bool>(),
It.IsAny<Predicate<object>>()))
.Callback<Action<object>, ThreadOption, bool, Predicate<object>>
((action, option, f, pred) => { subscribeCalled = true; });
eventAggregator
.Setup(x => x.GetEvent<SelectionChangedEvent>()).Returns(selectedEvent.Object);
var viewModel = new ViewModel(eventAggregator.Object);
Assert.That(subscribeCalled, Is.EqualTo(true));
}
The above is pretty ugly, mostly due to the fact the the only mockable (virtual) overload of the Event's Subscribe method takes four arguments and that the argument types of Callback() can't be deduced automatically - which leads to lots of "extraneous" code.
An alternative would be to instead mock EventBase.InternalSubscribe, which only takes a single argument; but as that method is protected this approach has its own caveats.
Related
I need to verify that the jqxgrid's 'rowClicked' action gets called using mocha unit tests in EmberJS. I have a grid initialized and can verify that it gets rendered, rows and headers are rendered, but I'm stuck on the rowclick event. I use jQuery to simulate a click on a row like this:
this.$('#row0grid_testgrid').trigger('click');
My grid code listens for the rowClick event like this:
this.grid().on('rowclick', function(evt) {
// My code here
});
How can I verify that this gets called?
Thanks
Can you do something like this - mocking functions?
/*** in your unit test ***/
//... get your grid object ...
const gridComponent = ....
// save the original function to assign it later back
const originalOn = gridComponent.on;
// now mock the on function
gridComponent.on = function(actionName, handler){
assert.ok(true, "on() function has been called");
assert.equal(actionName, "rowclick", "the action on which on() function has been triggered is correct");
}
// execute tested context
this.$('#row0grid_testgrid').trigger('click');
// tidy up
gridComponent.on = originalOn;
There are few things to mention here: if this works, you will test that on() has been called and that it was triggered on correct action 'rowclick'. However, you are still not able to test the part of your code "// My code here", within evented function.
If you want to test your evented function, what you can do is to call anonymous function from it. Let me show you what I mean:
/*** your component code ***/
// this will be called on "rowclick"
myComponentFunction: function(whatArgument){
// My code here
}
....
const self = this;
this.grid().on('rowclick', function(evt) {
// instead of pure code call a function
const someParameters = "foo";
self.myComponentFunction(someParameters);
});
...
In your unit test you are then able to mock also myComponentFunction:
// same unit test
....
const originalMyComponentFunction = gridComponent.myComponentFunction;
gridComponent.myComponentFunction = function(arg){
assert.ok(true, "myComponentFunction() has been called!");
// test argument, whatever
assert.equal(arg, "foo", "argument passed to myComponentFunction() from an event triggered on 'rowclick' is correct");
}
// tidy up myComponentFunction mock, too.
gridComponent.myComponentFunction = originalMyComponentFunction;
Btw, prefered way to set up mocks and tidy them up are to put it into beforeEach() and afterEach(), look at the ember-cli testing guides.
If you have any better idea how to test this, I would like to learn from you, too :)
I'm trying to test a react component.
var Component = React.createClass({
componentDidMount: function () {
return this.setState({
name: 'blabla'
});
},
render: function () {
return (
<h1>{this.state.name}</h1>
);
}
});
Is there a way, during testing, to mock what componentDidMount returns or does? That would leave me to test it on it's own and just test the component render behaviour.
Thanks!
I prefer the following approach, but requires using ES6 classes.
// component.jsx
class Component extends React.Component {
componentDidMount() { return this.setState({name: 'blabla'}); }
render() { return (<h1>{this.state.name}</h1>); }
}
//component-spec.jsx
describe('Component', () => {
it('does stuff', () => {
let ComponentTest = class extends Component {
componentDidMount() {
// your override here
}
};
let component = TestUtils.renderIntoDocument(<ComponentTest />);
//expect(component...).toEqual(...)
});
});
The point is to create an on demand ChildClass inheriting the OriginalClass,
do whatever overrides and then TestUtils.renderIntoDocument(<ChildClass />)
The idea here, if I understand correctly, is that you're trying to stub out a function before a component is rendered in your test. In your case, componentWillMount is only called once in a component's lifecycle, immediately before the component is rendered. So you can't just render the component and then stub out the function, it must be done before the render occurs.
Let's take these components for example:
parent.js
var Child = require('./child.js');
var Parent = React.createClass({
render : function () {
return (
<div className="parent">
<Child/>
</div>
);
}
});
module.exports = Parent;
child.js
var Child = React.createClass({
test : function () {
return true;
},
render : function () {
if (this.test) {
throw('boom');
}
return (
<div className="child">
Child
</div>
);
}
});
module.exports = Child;
Here, we would want to stub out the test function before our Child component is rendered, otherwise, it will blow up.
I have been able to do this using jasmine-react. These helper functions provide some useful functionality when running tests, almost to the point where TestUtils can be ditched completely.
jasmineReact.render(component, [container]) will render an instance of component into the DOM node specified in [container]. This is like TestUtils.renderIntoDocument(), except it renders the component into an attached DOM node instead of a detached DOM node. It will also perform the necessary cleaning operations when the test is finished.
jasmineReact.spyOnClass(componentClass, functionName) will stub out a particular function belonging to a component class. This behavior is maintained until the end of the test, which means that you can call this function before a component is rendered. This, if I understand correctly, is what you're looking for.
So, using these two helper functions, I can write a test for the code shown above that looks something like this:
var React = require('react/addons'),
Parent = require('./parent.js'),
Child = require('./child.js'),
jasmineReact = require('jasmine-react-helpers');
describe('Parent', function () {
it('does not blow up when rendering', function () {
jasmineReact.spyOnClass(Child, 'test').and.returnValue(false);
var parentInstance = jasmineReact.render(<Parent/>, document.body); //does not blow up
expect(parentInstance).toBeTruthy(); //passes
});
});
Let me know if you have any questions.
I've found two ways to go about this (i'm sure there are more).
1) I've used sinon-chai and required in the base element class and then use rewireify to put a set a spy on the componentWillMount method. This works but not sure what test suites you're using.
2) Probably the easier way. Is to just use the TestUtils to get an instance of the component and then just manually run the componentWillMount method.
That second way would probably look something like (forgive the pesudo code):
it('should call state when it first mounts', function () {
var Component = require('../my-component');
var component = TestUtils.renderIntoDocument(<Component />);
component.setState({name: null});
component.componentWillMount();
expect(component.state.name).to.equal('blabla');
});
I have a ViewModel which, in the constructor, makes a call to an async void method to add to a collection
public MyViewModel(ICommandHandler commandHandler)
{
_commandHandler = commandHandler;
SetupCollection();
}
private async void SetupCollection()
{
var commands = GetCommands();
foreach (var command in commands)
{
var response = await _commandHandler.ExecuteGetReply(command);
if (response != null)
Response.Add(response);
}
}
How exactly would I stub the _commandHandler.ExecuteGetReply() command to return a value?
Also, is it OK to have such a function in the constructor to do something like this? Or should this perhaps go within an... override void OnActivate() call (I'm using Caliburn Micro) ?
ICommandHandler.ExecuteGetReply appears to return a Task<Response> so you can do something like:
ICommand commandArg;
Response response;
stubHandler.Stub(h => h.ExecuteGetReply(commandArg)).Return(Task.FromResult(response));
I wouldn't call an async void method from your constructor however, since you will have no way of being notified when it has completed.
I have a method in a view just like following.
testMethod : function() {
//run code
}.observes('property1')
This method can either be trigerred directly by calling or triggered by the property1 observer. Is it possible to know inside the method, which way the call is getting triggered. Thanks
When observer is called, it receives 2 arguments: the controller object, and the observed property which has changed and triggered the observer.
So you can check it like this:
testMethod : function() {
if(arguments.length === 2 && arguments[1] === 'property1'){
// you're triggered by property observer
} else {
// triggered directly
}
}.observes('property1')
This, of course, can be spoofed by caller..
I have stumbled upon this myself and have found no way to do so. I ended up doing something like this:
testMethod : function() {
//run code
},
propertyObserver : function(){
this.testMethod();
}.observes('property1')
I have a method that performs an asynchronous service call. I call this class by passing in the callback.
public void GetRights(EventHandler<GetRightsCompletedEventArgs> callback)
{
ServiceClient client = new ServiceClient();
client.GetRightsCompleted += new EventHandler<GetRightsCompletedEventArgs>(callback);
client.GetRightsAsync();
}
GetRights(GetRightsCallback);
I'm creating tests with MSTest, and I've mocked the containing class (IGetRightsProxy) in Moq. How can I invoke the callback when this method is called in the test?
GetRightsForCurrentUserCompletedEventArgs results =
new GetRightsCompletedEventArgs(
new object[] { new ObservableCollection<Right>()}, null, false, null);
Mock<IGetRightsProxy> MockIGetRightsProxy = new Mock<GetRightsProxy>();
One way of doing what I want is to extend the class like this:
class MockGetRightsProxy : IGetRightsProxy
{
public void GetRights(EventHandler<GetRightsCompletedEventArgs> callback)
{
// Create some args here
GetRightsCompletedEventArgs args = new GetRightsCompletedEventArgs(
new object[] { new ObservableCollection<Right>() }, null, false, null);
callback(null, args);
}
}
I was looking for ways to invoke the callback in Moq, but this works, too.
You want to be looking at Moq's Callback() extension on your mock;
Mock<IGetRightsProxy> mock = new Mock<IGetRightsProxy>();
mock.Setup(x => x.GetRights(It.IsAny<EventHandler<GetRightsCompletedEventArgs>>())
.Callback<EventHandler<GetRightsCompletedEventArgs>>(
callback => callback(mock.Object, new GetRightsCompletedEventArgs())
);
When the code under test calls GetRights() on the IGetRightsProxy mock the actual EventHandler<GetRightsCompletedEventArgs> it passes in will subsequently be passed into Moq's Callback() method.
Note: Type inference will work on the generic applied to Callback() but I find in these cases it is a bit more readable to explicitly define the type being passed into the method.