Open frankandrobot opened 6 years ago
Let us know how that works out!
If you're testing redux, I'd make sure to do unit tests on the reducers themselves. It's easier but it's also way more robust.
Yea i got this working. Unfortunately, there's no code to share because it's closed source :( but here's an overview of what needs to happen:
ngtemplate-loader
and html-loader
to make webpack load the templates. The ngtemplate-loader instructions worked.Here's a minimal test example that uses karma and mocha:
import 'angularMocks';
import angular from 'angular';
import 'ng-redux';
import appReducers from '../../reducers';
import './user-completion.component';
import '../../app';
// Setup angular. Note that we need a working ngRedux for the template tests
angular.module('testConnect', ['ngRedux']).config([
'$ngReduxProvider',
function($ngReduxProvider) {
$ngReduxProvider.createStoreWith(appReducers, []);
},
]);
describe.only('component', function() {
let ngRedux;
beforeEach(angular.mock.module('testConnect'));
beforeEach(angular.mock.module('componentUnderTest'));
beforeEach(angular.mock.inject(function($ngRedux) {
ngRedux = $ngRedux;
}));
describe('with $compile', function() {
let element;
let scope;
beforeEach(
angular.mock.inject(function($rootScope, $compile) {
scope = $rootScope.$new();
element = angular.element('<component-under-test></component-under-test>');
element = $compile(element)(scope);
scope.$apply();
})
);
it('should show missing username', function() {
ngRedux.dispatch(updateState({
missing: {
username: true,
email: false,
},
}));
scope.$apply();
const result = element.html().toString();
expect(result).to.match(/Username/);
});
});
});
One of the things that I noticed, however, is that it's not obvious how to do fuller integration tests i.e., a test where everything is real except for AJAX requests. In our code base we are already doing this when testing sagas. Unfortunately, for this to work we use redux-mock-store-middleware
which allows a fully working store with getActions
and resetActions
functionality (needed for testing).
So... to make these types of integration tests work with templates, we need the ngRedux magic of reduxifying angular components and the redux-mock-store-middleware
functionality. Hmm.... since it is middleware, I could probably still use it. However, our tests recreate the store on each test (that means we get a fresh copy of the redux state each test)... I don't see an obvious way of doing that (meaning tests won't be independent).
Update: I suppose there's this: https://stackoverflow.com/questions/35622588/how-to-reset-the-state-of-a-redux-store/35641992#35641992 The downside is that tests start to get a lot of boilerplate
Have you guys had any luck unit testing components? (See for example, https://puigcerber.com/2016/02/07/how-to-test-angular-1-5-components/)
I've currently configured angular 1.5, ngtemplate-loader, and webpack to load the HTML partials correctly in karma but tests are erring out with the following ngRedux error:
Update: oh wait, I probably have to configure ngRedux in tests as well (doh)